update to 0.9.15
Signed-off-by: Олег Зонов <me.OZone@Gmail.com> (github: OZ1)
|
@ -1,123 +1,167 @@
|
||||||
@echo OFF
|
@echo OFF
|
||||||
|
|
||||||
FOR /F "tokens=1,2* delims= " %%i in (Version) do set "%%i=%%j"
|
FOR /F "tokens=1,2* delims= " %%i in (Version) do set "%%i=%%j"
|
||||||
|
|
||||||
if %DevChannel% neq 0 goto preparedev
|
set "VersionForPacker=%AppVersion%"
|
||||||
|
if %BetaVersion% neq 0 (
|
||||||
set "DevParam="
|
set "AppVersion=%BetaVersion%"
|
||||||
set "AppVersionStrFull=%AppVersionStr%"
|
set "AppVersionStrFull=%AppVersionStr%_%BetaVersion%"
|
||||||
goto devprepared
|
set "DevParam=-beta %BetaVersion%"
|
||||||
|
set "BetaKeyFile=tbeta_%BetaVersion%_key"
|
||||||
:preparedev
|
) else (
|
||||||
|
if %DevChannel% neq 0 (
|
||||||
set "DevParam=-dev"
|
set "DevParam=-dev"
|
||||||
set "AppVersionStrFull=%AppVersionStr%.dev"
|
set "AppVersionStrFull=%AppVersionStr%.dev"
|
||||||
|
) else (
|
||||||
:devprepared
|
set "DevParam="
|
||||||
|
set "AppVersionStrFull=%AppVersionStr%"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Building version %AppVersionStrFull% for Windows..
|
echo Building version %AppVersionStrFull% for Windows..
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
if exist ..\Win32\Deploy\deploy\%AppVersionStrMajor%\%AppVersionStr%\ goto error_exist1
|
set "UpdateFile=tupdate%AppVersion%"
|
||||||
if exist ..\Win32\Deploy\deploy\%AppVersionStrMajor%\%AppVersionStr%.dev\ goto error_exist2
|
set "SetupFile=tsetup.%AppVersionStrFull%.exe"
|
||||||
if exist ..\Win32\Deploy\tupdate%AppVersion% goto error_exist3
|
set "PortableFile=tportable.%AppVersionStrFull%.zip"
|
||||||
|
set "HomePath=..\..\Telegram"
|
||||||
|
set "ReleasePath=..\Win32\Deploy"
|
||||||
|
set "DeployPath=%ReleasePath%\deploy\%AppVersionStrMajor%\%AppVersionStrFull%"
|
||||||
|
set "SignPath=..\..\TelegramPrivate\Sign.bat"
|
||||||
|
|
||||||
|
if %BetaVersion% neq 0 (
|
||||||
|
if exist %ReleasePath%\%BetaKeyFile% (
|
||||||
|
echo Beta version key file for version %AppVersion% already exists!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
if exist %ReleasePath%\deploy\%AppVersionStrMajor%\%AppVersionStr%.dev\ (
|
||||||
|
echo Deploy folder for version %AppVersionStr%.dev already exists!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
if exist %ReleasePath%\tupdate%AppVersion% (
|
||||||
|
echo Update file for version %AppVersion% already exists!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if exist %ReleasePath%\deploy\%AppVersionStrMajor%\%AppVersionStr%\ (
|
||||||
|
echo Deploy folder for version %AppVersionStr% already exists!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
cd SourceFiles\
|
cd SourceFiles\
|
||||||
copy telegram.qrc /B+,,/Y
|
rem copy telegram.qrc /B+,,/Y
|
||||||
cd ..\
|
cd ..\
|
||||||
if %errorlevel% neq 0 goto error
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
cd ..\
|
cd ..\
|
||||||
MSBuild Telegram.sln /property:Configuration=Deploy
|
MSBuild Telegram.sln /property:Configuration=Deploy
|
||||||
if %errorlevel% neq 0 goto error0
|
cd Telegram\
|
||||||
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
echo .
|
echo .
|
||||||
echo Version %AppVersionStrFull% build successfull! Preparing..
|
echo Version %AppVersionStrFull% build successfull. Preparing..
|
||||||
echo .
|
echo .
|
||||||
|
|
||||||
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"
|
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"
|
||||||
cd Win32\Deploy\
|
|
||||||
|
|
||||||
call ..\..\..\TelegramPrivate\Sign.bat Telegram.exe
|
call %SignPath% %ReleasePath%\Telegram.exe
|
||||||
if %errorlevel% neq 0 goto error1
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
call ..\..\..\TelegramPrivate\Sign.bat Updater.exe
|
call %SignPath% %ReleasePath%\Updater.exe
|
||||||
if %errorlevel% neq 0 goto error1
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
iscc /dMyAppVersion=%AppVersionStrSmall% /dMyAppVersionZero=%AppVersionStr% /dMyAppVersionFull=%AppVersionStrFull% ..\..\Telegram\Setup.iss
|
if %BetaVersion% equ 0 (
|
||||||
if %errorlevel% neq 0 goto error1
|
cd %ReleasePath%
|
||||||
|
iscc /dMyAppVersion=%AppVersionStrSmall% /dMyAppVersionZero=%AppVersionStr% /dMyAppVersionFull=%AppVersionStrFull% %HomePath%\Setup.iss
|
||||||
|
cd %HomePath%
|
||||||
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
call ..\..\..\TelegramPrivate\Sign.bat tsetup.%AppVersionStrFull%.exe
|
call %SignPath% %ReleasePath%\tsetup.%AppVersionStrFull%.exe
|
||||||
if %errorlevel% neq 0 goto error1
|
if %errorlevel% neq 0 goto error
|
||||||
|
)
|
||||||
|
|
||||||
call Packer.exe -version %AppVersion% -path Telegram.exe -path Updater.exe %DevParam%
|
cd %ReleasePath%
|
||||||
if %errorlevel% neq 0 goto error1
|
call Packer.exe -version %VersionForPacker% -path Telegram.exe -path Updater.exe %DevParam%
|
||||||
|
cd %HomePath%
|
||||||
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
if not exist deploy mkdir deploy
|
if %BetaVersion% neq 0 (
|
||||||
if not exist deploy\%AppVersionStrMajor% mkdir deploy\%AppVersionStrMajor%
|
if not exist %ReleasePath%\%BetaKeyFile% (
|
||||||
mkdir deploy\%AppVersionStrMajor%\%AppVersionStrFull%
|
echo Beta version key file not found!
|
||||||
mkdir deploy\%AppVersionStrMajor%\%AppVersionStrFull%\Telegram
|
exit /b 1
|
||||||
if %errorlevel% neq 0 goto error1
|
)
|
||||||
|
|
||||||
move Telegram.exe deploy\%AppVersionStrMajor%\%AppVersionStrFull%\Telegram\
|
FOR /F "tokens=1* delims= " %%i in (%ReleasePath%\%BetaKeyFile%) do set "BetaSignature=%%i"
|
||||||
move Updater.exe deploy\%AppVersionStrMajor%\%AppVersionStrFull%\
|
)
|
||||||
move Telegram.pdb deploy\%AppVersionStrMajor%\%AppVersionStrFull%\
|
if %errorlevel% neq 0 goto error
|
||||||
move Updater.pdb deploy\%AppVersionStrMajor%\%AppVersionStrFull%\
|
|
||||||
move tsetup.%AppVersionStrFull%.exe deploy\%AppVersionStrMajor%\%AppVersionStrFull%\
|
|
||||||
move tupdate%AppVersion% deploy\%AppVersionStrMajor%\%AppVersionStrFull%\
|
|
||||||
if %errorlevel% neq 0 goto error1
|
|
||||||
|
|
||||||
cd deploy\%AppVersionStrMajor%\%AppVersionStrFull%\
|
if %BetaVersion% neq 0 (
|
||||||
7z a -mx9 tportable.%AppVersionStrFull%.zip Telegram\
|
set "UpdateFile=%UpdateFile%_%BetaSignature%"
|
||||||
if %errorlevel% neq 0 goto error2
|
set "PortableFile=tbeta%BetaVersion%_%BetaSignature%.zip"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not exist %ReleasePath%\deploy mkdir %ReleasePath%\deploy
|
||||||
|
if not exist %ReleasePath%\deploy\%AppVersionStrMajor% mkdir %ReleasePath%\deploy\%AppVersionStrMajor%
|
||||||
|
mkdir %DeployPath%
|
||||||
|
mkdir %DeployPath%\Telegram
|
||||||
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
|
move %ReleasePath%\Telegram.exe %DeployPath%\Telegram\
|
||||||
|
move %ReleasePath%\Updater.exe %DeployPath%\
|
||||||
|
move %ReleasePath%\Telegram.pdb %DeployPath%\
|
||||||
|
move %ReleasePath%\Updater.pdb %DeployPath%\
|
||||||
|
if %BetaVersion% equ 0 (
|
||||||
|
move %ReleasePath%\%SetupFile% %DeployPath%\
|
||||||
|
) else (
|
||||||
|
move %ReleasePath%\%BetaKeyFile% %DeployPath%\
|
||||||
|
)
|
||||||
|
move %ReleasePath%\%UpdateFile% %DeployPath%\
|
||||||
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
|
cd %DeployPath%\
|
||||||
|
7z a -mx9 %PortableFile% Telegram\
|
||||||
|
cd ..\..\..\%HomePath%\
|
||||||
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
echo .
|
echo .
|
||||||
echo Version %AppVersionStrFull% is ready for deploy!
|
echo Version %AppVersionStrFull% is ready for deploy!
|
||||||
echo .
|
echo .
|
||||||
|
|
||||||
if not exist tupdate%AppVersion% goto error2
|
set "FinalReleasePath=Z:\TBuild\tother\tsetup"
|
||||||
if not exist tportable.%AppVersionStrFull%.zip goto error2
|
set "FinalDeployPath=%FinalReleasePath%\%AppVersionStrMajor%\%AppVersionStrFull%"
|
||||||
if not exist tsetup.%AppVersionStrFull%.exe goto error2
|
|
||||||
if not exist Telegram.pdb goto error2
|
|
||||||
if not exist Updater.exe goto error2
|
|
||||||
if not exist Updater.pdb goto error2
|
|
||||||
if not exist Z:\TBuild\tother\tsetup\%AppVersionStrMajor% mkdir Z:\TBuild\tother\tsetup\%AppVersionStrMajor%
|
|
||||||
if not exist Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull% mkdir Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull%
|
|
||||||
|
|
||||||
xcopy tupdate%AppVersion% Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull%\
|
if not exist %DeployPath%\%UpdateFile% goto error
|
||||||
xcopy tportable.%AppVersionStrFull%.zip Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull%\
|
if not exist %DeployPath%\%PortableFile% goto error
|
||||||
xcopy tsetup.%AppVersionStrFull%.exe Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull%\
|
if %BetaVersion% equ 0 (
|
||||||
xcopy Telegram.pdb Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull%\
|
if not exist %DeployPath%\%SetupFile% goto error
|
||||||
xcopy Updater.exe Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull%\
|
)
|
||||||
xcopy Updater.pdb Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStrFull%\
|
if not exist %DeployPath%\Telegram.pdb goto error
|
||||||
|
if not exist %DeployPath%\Updater.exe goto error
|
||||||
|
if not exist %DeployPath%\Updater.pdb goto error
|
||||||
|
if not exist %FinalReleasePath%\%AppVersionStrMajor% mkdir %FinalReleasePath%\%AppVersionStrMajor%
|
||||||
|
if not exist %FinalDeployPath% mkdir %FinalDeployPath%
|
||||||
|
|
||||||
|
xcopy %DeployPath%\%UpdateFile% %FinalDeployPath%\
|
||||||
|
xcopy %DeployPath%\%PortableFile% %FinalDeployPath%\
|
||||||
|
if %BetaVersion% equ 0 (
|
||||||
|
xcopy %DeployPath%\%SetupFile% %FinalDeployPath%\
|
||||||
|
) else (
|
||||||
|
xcopy %DeployPath%\%BetaKeyFile% %FinalDeployPath%\
|
||||||
|
)
|
||||||
|
xcopy %DeployPath%\Telegram.pdb %FinalDeployPath%\
|
||||||
|
xcopy %DeployPath%\Updater.exe %FinalDeployPath%\
|
||||||
|
xcopy %DeployPath%\Updater.pdb %FinalDeployPath%\
|
||||||
|
|
||||||
echo Version %AppVersionStrFull% is ready!
|
echo Version %AppVersionStrFull% is ready!
|
||||||
|
|
||||||
cd ..\..\..\..\..\Telegram\
|
|
||||||
goto eof
|
goto eof
|
||||||
|
|
||||||
:error2
|
|
||||||
cd ..\..\..\
|
|
||||||
:error1
|
|
||||||
cd ..\..\
|
|
||||||
:error0
|
|
||||||
cd Telegram\
|
|
||||||
goto error
|
|
||||||
|
|
||||||
:error_exist1
|
|
||||||
echo Deploy folder for version %AppVersionStr% already exists!
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:error_exist2
|
|
||||||
echo Deploy folder for version %AppVersionStr%.dev already exists!
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:error_exist3
|
|
||||||
echo Update file for version %AppVersion% already exists!
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:error
|
:error
|
||||||
echo ERROR occured!
|
echo ERROR occured!
|
||||||
exit /b %errorlevel%
|
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
:eof
|
:eof
|
||||||
|
|
|
@ -5,9 +5,16 @@ while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
eval $1="$2"
|
eval $1="$2"
|
||||||
done < Version
|
done < Version
|
||||||
|
|
||||||
AppVersionStrFull="$AppVersionStr"
|
VersionForPacker="$AppVersion"
|
||||||
DevParam=''
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
if [ "$DevChannel" != "0" ]; then
|
AppVersion="$BetaVersion"
|
||||||
|
AppVersionStrFull="${AppVersionStr}_${BetaVersion}"
|
||||||
|
DevParam="-beta $BetaVersion"
|
||||||
|
BetaKeyFile="tbeta_${AppVersion}_key"
|
||||||
|
elif [ "$DevChannel" == "0" ]; then
|
||||||
|
AppVersionStrFull="$AppVersionStr"
|
||||||
|
DevParam=''
|
||||||
|
else
|
||||||
AppVersionStrFull="$AppVersionStr.dev"
|
AppVersionStrFull="$AppVersionStr.dev"
|
||||||
DevParam='-dev'
|
DevParam='-dev'
|
||||||
fi
|
fi
|
||||||
|
@ -22,12 +29,12 @@ while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
done < Target
|
done < Target
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
HomePath="./../../Telegram"
|
||||||
if [ "$BuildTarget" == "linux" ]; then
|
if [ "$BuildTarget" == "linux" ]; then
|
||||||
echo "Building version $AppVersionStrFull for Linux 64bit.."
|
echo "Building version $AppVersionStrFull for Linux 64bit.."
|
||||||
UpdateFile="tlinuxupd$AppVersion"
|
UpdateFile="tlinuxupd$AppVersion"
|
||||||
SetupFile="tsetup.$AppVersionStrFull.tar.xz"
|
SetupFile="tsetup.$AppVersionStrFull.tar.xz"
|
||||||
WorkPath="./../Linux"
|
WorkPath="./../Linux"
|
||||||
HomePath="./../../Telegram"
|
|
||||||
FixScript="$HomePath/FixMake.sh"
|
FixScript="$HomePath/FixMake.sh"
|
||||||
ReleasePath="./../Linux/Release"
|
ReleasePath="./../Linux/Release"
|
||||||
elif [ "$BuildTarget" == "linux32" ]; then
|
elif [ "$BuildTarget" == "linux32" ]; then
|
||||||
|
@ -35,7 +42,6 @@ elif [ "$BuildTarget" == "linux32" ]; then
|
||||||
UpdateFile="tlinux32upd$AppVersion"
|
UpdateFile="tlinux32upd$AppVersion"
|
||||||
SetupFile="tsetup32.$AppVersionStrFull.tar.xz"
|
SetupFile="tsetup32.$AppVersionStrFull.tar.xz"
|
||||||
WorkPath="./../Linux"
|
WorkPath="./../Linux"
|
||||||
HomePath="./../../Telegram"
|
|
||||||
FixScript="$HomePath/FixMake32.sh"
|
FixScript="$HomePath/FixMake32.sh"
|
||||||
ReleasePath="./../Linux/Release"
|
ReleasePath="./../Linux/Release"
|
||||||
elif [ "$BuildTarget" == "mac" ]; then
|
elif [ "$BuildTarget" == "mac" ]; then
|
||||||
|
@ -51,6 +57,11 @@ elif [ "$BuildTarget" == "mac32" ]; then
|
||||||
ReleasePath="./../Mac/Release"
|
ReleasePath="./../Mac/Release"
|
||||||
BinaryName="Telegram"
|
BinaryName="Telegram"
|
||||||
elif [ "$BuildTarget" == "macstore" ]; then
|
elif [ "$BuildTarget" == "macstore" ]; then
|
||||||
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
echo "Can't build macstore beta version!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Building version $AppVersionStrFull for Mac App Store.."
|
echo "Building version $AppVersionStrFull for Mac App Store.."
|
||||||
ReleasePath="./../Mac/Release"
|
ReleasePath="./../Mac/Release"
|
||||||
BinaryName="Telegram Desktop"
|
BinaryName="Telegram Desktop"
|
||||||
|
@ -62,19 +73,31 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
#if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
||||||
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
if [ -f "$ReleasePath/$BetaKeyFile" ]; then
|
||||||
|
echo "Beta version key file for version $AppVersion already exists!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull" ]; then
|
||||||
|
echo "Deploy folder for version $AppVersionStrFull already exists!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
if [ -d "$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStr.dev" ]; then
|
if [ -d "$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStr.dev" ]; then
|
||||||
echo "Deploy folder for version $AppVersionStr.dev already exists!"
|
echo "Deploy folder for version $AppVersionStr.dev already exists!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -f "$ReleasePath/$UpdateFile" ]; then
|
||||||
|
echo "Update file for version $AppVersion already exists!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -d "$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStr" ]; then
|
if [ -d "$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStr" ]; then
|
||||||
echo "Deploy folder for version $AppVersionStr already exists!"
|
echo "Deploy folder for version $AppVersionStr already exists!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$ReleasePath/$UpdateFile" ]; then
|
|
||||||
echo "Update file for version $AppVersion already exists!"
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DeployPath="$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull"
|
DeployPath="$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull"
|
||||||
|
@ -106,9 +129,23 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Preparing version $AppVersionStrFull, executing Packer.."
|
echo "Preparing version $AppVersionStrFull, executing Packer.."
|
||||||
cd $ReleasePath && ./Packer -path Telegram -path Updater -version $AppVersion $DevParam && cd ./../../Telegram
|
cd "$ReleasePath" && "./Packer" -path Telegram -path Updater -version $VersionForPacker $DevParam && cd "$HomePath"
|
||||||
echo "Packer done!"
|
echo "Packer done!"
|
||||||
|
|
||||||
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
if [ ! -f "$ReleasePath/$BetaKeyFile" ]; then
|
||||||
|
echo "Beta version key file not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
|
BetaSignature="$line"
|
||||||
|
done < "$ReleasePath/$BetaKeyFile"
|
||||||
|
|
||||||
|
UpdateFile="${UpdateFile}_${BetaSignature}"
|
||||||
|
SetupFile="tbeta${BetaVersion}_${BetaSignature}.tar.xz"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -d "$ReleasePath/deploy" ]; then
|
if [ ! -d "$ReleasePath/deploy" ]; then
|
||||||
mkdir "$ReleasePath/deploy"
|
mkdir "$ReleasePath/deploy"
|
||||||
fi
|
fi
|
||||||
|
@ -120,15 +157,18 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
||||||
echo "Copying Telegram, Updater and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStrFull..";
|
echo "Copying Telegram, Updater and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStrFull..";
|
||||||
mkdir "$DeployPath"
|
mkdir "$DeployPath"
|
||||||
mkdir "$DeployPath/Telegram"
|
mkdir "$DeployPath/Telegram"
|
||||||
mv $ReleasePath/Telegram $DeployPath/Telegram/
|
mv "$ReleasePath/Telegram" "$DeployPath/Telegram/"
|
||||||
mv $ReleasePath/Updater $DeployPath/Telegram/
|
mv "$ReleasePath/Updater" "$DeployPath/Telegram/"
|
||||||
mv $ReleasePath/$UpdateFile $DeployPath/
|
mv "$ReleasePath/$UpdateFile" "$DeployPath/"
|
||||||
cd $DeployPath && tar -cJvf $SetupFile Telegram/ && cd ./../../../../../Telegram
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
mv "$ReleasePath/$BetaKeyFile" "$DeployPath/"
|
||||||
|
fi
|
||||||
|
cd "$DeployPath" && tar -cJvf "$SetupFile" "Telegram/" && cd "./../../../$HomePath"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
||||||
|
|
||||||
touch ./SourceFiles/telegram.qrc
|
touch "./SourceFiles/telegram.qrc"
|
||||||
xcodebuild -project Telegram.xcodeproj -alltargets -configuration Release build
|
xcodebuild -project Telegram.xcodeproj -alltargets -configuration Release build
|
||||||
|
|
||||||
if [ ! -d "$ReleasePath/$BinaryName.app" ]; then
|
if [ ! -d "$ReleasePath/$BinaryName.app" ]; then
|
||||||
|
@ -176,14 +216,31 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
||||||
cd $ReleasePath
|
if [ "$BetaVersion" == "0" ]; then
|
||||||
|
cd "$ReleasePath"
|
||||||
temppath=`hdiutil attach -readwrite tsetup.dmg | awk -F "\t" 'END {print $3}'`
|
temppath=`hdiutil attach -readwrite tsetup.dmg | awk -F "\t" 'END {print $3}'`
|
||||||
cp -R "./$BinaryName.app" "$temppath/"
|
cp -R "./$BinaryName.app" "$temppath/"
|
||||||
bless --folder "$temppath/" --openfolder "$temppath/"
|
bless --folder "$temppath/" --openfolder "$temppath/"
|
||||||
hdiutil detach "$temppath"
|
hdiutil detach "$temppath"
|
||||||
hdiutil convert tsetup.dmg -format UDZO -imagekey zlib-level=9 -ov -o $SetupFile
|
hdiutil convert tsetup.dmg -format UDZO -imagekey zlib-level=9 -ov -o "$SetupFile"
|
||||||
cd ./../../Telegram
|
cd "./../../Telegram"
|
||||||
cd $ReleasePath && ./Packer.app/Contents/MacOS/Packer -path "$BinaryName.app" -version $AppVersion $DevParam && cd ./../../Telegram
|
fi
|
||||||
|
cd "$ReleasePath" && "./Packer.app/Contents/MacOS/Packer" -path "$BinaryName.app" -version $VersionForPacker $DevParam && cd "$HomePath"
|
||||||
|
echo "Packer done!"
|
||||||
|
|
||||||
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
if [ ! -f "$ReleasePath/$BetaKeyFile" ]; then
|
||||||
|
echo "Beta version key file not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
|
BetaSignature="$line"
|
||||||
|
done < "$ReleasePath/$BetaKeyFile"
|
||||||
|
|
||||||
|
UpdateFile="${UpdateFile}_${BetaSignature}"
|
||||||
|
SetupFile="tbeta${BetaVersion}_${BetaSignature}.zip"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "$ReleasePath/deploy" ]; then
|
if [ ! -d "$ReleasePath/deploy" ]; then
|
||||||
|
@ -198,13 +255,17 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||||
echo "Copying $BinaryName.app and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStr..";
|
echo "Copying $BinaryName.app and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStr..";
|
||||||
mkdir "$DeployPath"
|
mkdir "$DeployPath"
|
||||||
mkdir "$DeployPath/Telegram"
|
mkdir "$DeployPath/Telegram"
|
||||||
cp -r "$ReleasePath/$BinaryName.app" $DeployPath/Telegram/
|
cp -r "$ReleasePath/$BinaryName.app" "$DeployPath/Telegram/"
|
||||||
mv "$ReleasePath/$BinaryName.app.dSYM" $DeployPath/
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
cd "$DeployPath" && zip -r "$SetupFile" "Telegram" && mv "$SetupFile" "./../../../" && cd "./../../../$HomePath"
|
||||||
|
mv "$ReleasePath/$BetaKeyFile" "$DeployPath/"
|
||||||
|
fi
|
||||||
|
mv "$ReleasePath/$BinaryName.app.dSYM" "$DeployPath/"
|
||||||
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
|
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
|
||||||
rm "$ReleasePath/$BinaryName.app/Contents/Frameworks/Updater"
|
rm "$ReleasePath/$BinaryName.app/Contents/Frameworks/Updater"
|
||||||
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
|
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
|
||||||
mv $ReleasePath/$UpdateFile $DeployPath/
|
mv "$ReleasePath/$UpdateFile" "$DeployPath/"
|
||||||
mv $ReleasePath/$SetupFile $DeployPath/
|
mv "$ReleasePath/$SetupFile" "$DeployPath/"
|
||||||
|
|
||||||
if [ "$BuildTarget" == "mac32" ]; then
|
if [ "$BuildTarget" == "mac32" ]; then
|
||||||
ReleaseToPath="./../../../TBuild/tother/tmac32"
|
ReleaseToPath="./../../../TBuild/tother/tmac32"
|
||||||
|
@ -217,16 +278,19 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||||
mkdir "$DeployToPath"
|
mkdir "$DeployToPath"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp -v $DeployPath/$UpdateFile $DeployToPath/
|
cp -v "$DeployPath/$UpdateFile" "$DeployToPath/"
|
||||||
cp -v $DeployPath/$SetupFile $DeployToPath/
|
cp -v "$DeployPath/$SetupFile" "$DeployToPath/"
|
||||||
cp -rv $DeployPath/$BinaryName.app.dSYM $DeployToPath/
|
cp -rv "$DeployPath/$BinaryName.app.dSYM" "$DeployToPath/"
|
||||||
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
cp -v "$DeployPath/$BetaKeyFile" "$DeployToPath/"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
elif [ "$BuildTarget" == "macstore" ]; then
|
elif [ "$BuildTarget" == "macstore" ]; then
|
||||||
echo "Copying $BinaryName.app to deploy/$AppVersionStrMajor/$AppVersionStr..";
|
echo "Copying $BinaryName.app to deploy/$AppVersionStrMajor/$AppVersionStr..";
|
||||||
mkdir "$DeployPath"
|
mkdir "$DeployPath"
|
||||||
cp -r "$ReleasePath/$BinaryName.app" $DeployPath/
|
cp -r "$ReleasePath/$BinaryName.app" "$DeployPath/"
|
||||||
mv "$ReleasePath/$BinaryName.pkg" $DeployPath/
|
mv "$ReleasePath/$BinaryName.pkg" "$DeployPath/"
|
||||||
mv "$ReleasePath/$BinaryName.app.dSYM" $DeployPath/
|
mv "$ReleasePath/$BinaryName.app.dSYM" "$DeployPath/"
|
||||||
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
|
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
|
||||||
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
|
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
DeployTarget="$1"
|
||||||
|
|
||||||
while IFS='' read -r line || [[ -n "$line" ]]; do
|
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
set $line
|
set $line
|
||||||
eval $1="$2"
|
eval $1="$2"
|
||||||
done < Version
|
done < Version
|
||||||
|
|
||||||
AppVersionStrFull="$AppVersionStr"
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
DevParam=''
|
AppVersion="$BetaVersion"
|
||||||
if [ "$DevChannel" != "0" ]; then
|
AppVersionStrFull="${AppVersionStr}_${BetaVersion}"
|
||||||
|
DevParam="-beta $BetaVersion"
|
||||||
|
BetaKeyFile="tbeta_${AppVersion}_key"
|
||||||
|
elif [ "$DevChannel" == "0" ]; then
|
||||||
|
AppVersionStrFull="$AppVersionStr"
|
||||||
|
DevParam=''
|
||||||
|
else
|
||||||
AppVersionStrFull="$AppVersionStr.dev"
|
AppVersionStrFull="$AppVersionStr.dev"
|
||||||
DevParam='-dev'
|
DevParam='-dev'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "Target" ]; then
|
if [ ! -f "Target" ]; then
|
||||||
echo "Build target not found!"
|
echo "Deploy target not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -35,7 +43,24 @@ elif [ "$BuildTarget" == "linux32" ]; then
|
||||||
ReleasePath="./../Linux/Release"
|
ReleasePath="./../Linux/Release"
|
||||||
RemoteFolder="tlinux32"
|
RemoteFolder="tlinux32"
|
||||||
elif [ "$BuildTarget" == "mac" ]; then
|
elif [ "$BuildTarget" == "mac" ]; then
|
||||||
|
DeployMac="0"
|
||||||
|
DeployMac32="0"
|
||||||
|
DeployWin="0"
|
||||||
|
if [ "$DeployTarget" == "mac" ]; then
|
||||||
|
DeployMac="1"
|
||||||
|
echo "Deploying version $AppVersionStrFull for OS X 10.8+.."
|
||||||
|
elif [ "$DeployTarget" == "mac32" ]; then
|
||||||
|
DeployMac32="1"
|
||||||
|
echo "Deploying version $AppVersionStrFull for OS X 10.6 and 10.7.."
|
||||||
|
elif [ "$DeployTarget" == "win" ]; then
|
||||||
|
DeployWin="1"
|
||||||
|
echo "Deploying version $AppVersionStrFull for Windows.."
|
||||||
|
else
|
||||||
|
DeployMac="1"
|
||||||
|
DeployMac32="1"
|
||||||
|
DeployWin="1"
|
||||||
echo "Deploying three versions of $AppVersionStrFull: for Windows, OS X 10.6 and 10.7 and OS X 10.8+.."
|
echo "Deploying three versions of $AppVersionStrFull: for Windows, OS X 10.6 and 10.7 and OS X 10.8+.."
|
||||||
|
fi
|
||||||
UpdateFile="tmacupd$AppVersion"
|
UpdateFile="tmacupd$AppVersion"
|
||||||
SetupFile="tsetup.$AppVersionStrFull.dmg"
|
SetupFile="tsetup.$AppVersionStrFull.dmg"
|
||||||
ReleasePath="./../Mac/Release"
|
ReleasePath="./../Mac/Release"
|
||||||
|
@ -51,6 +76,8 @@ elif [ "$BuildTarget" == "mac" ]; then
|
||||||
WinRemoteFolder="tsetup"
|
WinRemoteFolder="tsetup"
|
||||||
DropboxPath="./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor"
|
DropboxPath="./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor"
|
||||||
DropboxDeployPath="$DropboxPath/$AppVersionStrFull"
|
DropboxDeployPath="$DropboxPath/$AppVersionStrFull"
|
||||||
|
DropboxSetupFile="$SetupFile"
|
||||||
|
DropboxMac32SetupFile="$Mac32SetupFile"
|
||||||
elif [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" = "macstore" ]; then
|
elif [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" = "macstore" ]; then
|
||||||
echo "No need to deploy this target."
|
echo "No need to deploy this target."
|
||||||
exit
|
exit
|
||||||
|
@ -61,8 +88,40 @@ fi
|
||||||
|
|
||||||
DeployPath="$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull"
|
DeployPath="$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull"
|
||||||
|
|
||||||
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
if [ "$DeployTarget" == "win" ]; then
|
||||||
|
BetaFilePath="$WinDeployPath/$BetaKeyFile"
|
||||||
|
elif [ "$DeployTarget" == "mac32" ]; then
|
||||||
|
BetaFilePath="$Mac32DeployPath/$BetaKeyFile"
|
||||||
|
else
|
||||||
|
BetaFilePath="$DeployPath/$BetaKeyFile"
|
||||||
|
fi
|
||||||
|
if [ ! -f "$BetaFilePath" ]; then
|
||||||
|
echo "Beta key file for $AppVersionStrFull not found :("
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
|
BetaSignature="$line"
|
||||||
|
done < "$BetaFilePath"
|
||||||
|
|
||||||
|
UpdateFile="${UpdateFile}_${BetaSignature}"
|
||||||
|
if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
||||||
|
SetupFile="tbeta${BetaVersion}_${BetaSignature}.tar.xz"
|
||||||
|
elif [ "$BuildTarget" == "mac" ]; then
|
||||||
|
SetupFile="tbeta${BetaVersion}_${BetaSignature}.zip"
|
||||||
|
DropboxSetupFile="tbeta${BetaVersion}_${BetaSignature}_mac.zip"
|
||||||
|
Mac32UpdateFile="${Mac32UpdateFile}_${BetaSignature}"
|
||||||
|
Mac32SetupFile="tbeta${BetaVersion}_${BetaSignature}.zip"
|
||||||
|
DropboxMac32SetupFile="tbeta${BetaVersion}_${BetaSignature}_mac32.zip"
|
||||||
|
WinUpdateFile="${WinUpdateFile}_${BetaSignature}"
|
||||||
|
WinPortableFile="tbeta${BetaVersion}_${BetaSignature}.zip"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
#if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
#if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
||||||
|
|
||||||
|
if [ "$BuildTarget" != "mac" ] || [ "$DeployMac" == "1" ]; then
|
||||||
if [ ! -f "$DeployPath/$UpdateFile" ]; then
|
if [ ! -f "$DeployPath/$UpdateFile" ]; then
|
||||||
echo "$UpdateFile not found!";
|
echo "$UpdateFile not found!";
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -72,8 +131,10 @@ DeployPath="$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull"
|
||||||
echo "$SetupFile not found!"
|
echo "$SetupFile not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$BuildTarget" == "mac" ]; then
|
if [ "$BuildTarget" == "mac" ]; then
|
||||||
|
if [ "$DeployMac32" == "1" ]; then
|
||||||
if [ ! -f "$Mac32DeployPath/$Mac32UpdateFile" ]; then
|
if [ ! -f "$Mac32DeployPath/$Mac32UpdateFile" ]; then
|
||||||
echo "$Mac32UpdateFile not found!"
|
echo "$Mac32UpdateFile not found!"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -83,47 +144,81 @@ DeployPath="$ReleasePath/deploy/$AppVersionStrMajor/$AppVersionStrFull"
|
||||||
echo "$Mac32SetupFile not found!"
|
echo "$Mac32SetupFile not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DeployWin" == "1" ]; then
|
||||||
if [ ! -f "$WinDeployPath/$WinUpdateFile" ]; then
|
if [ ! -f "$WinDeployPath/$WinUpdateFile" ]; then
|
||||||
echo "$WinUpdateFile not found!"
|
echo "$WinUpdateFile not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$BetaVersion" == "0" ]; then
|
||||||
if [ ! -f "$WinDeployPath/$WinSetupFile" ]; then
|
if [ ! -f "$WinDeployPath/$WinSetupFile" ]; then
|
||||||
echo "$WinSetupFile not found!"
|
echo "$WinSetupFile not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -f "$WinDeployPath/$WinPortableFile" ]; then
|
if [ ! -f "$WinDeployPath/$WinPortableFile" ]; then
|
||||||
echo "$WinPortableFile not found!"
|
echo "$WinPortableFile not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -d "./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor" ]; then
|
if [ ! -d "$DropboxPath" ]; then
|
||||||
mkdir "./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor"
|
mkdir "$DropboxPath"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$DropboxDeployPath" ]; then
|
||||||
|
mkdir "$DropboxDeployPath"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
#fi
|
#fi
|
||||||
|
|
||||||
if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$BuildTarget" == "mac" ]; then
|
if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$BuildTarget" == "mac" ]; then
|
||||||
|
if [ "$BuildTarget" != "mac" ] || [ "$DeployMac" == "1" ]; then
|
||||||
scp "$DeployPath/$UpdateFile" "tmaster:tdesktop/www/$RemoteFolder/"
|
scp "$DeployPath/$UpdateFile" "tmaster:tdesktop/www/$RemoteFolder/"
|
||||||
scp "$DeployPath/$SetupFile" "tmaster:tdesktop/www/$RemoteFolder/"
|
scp "$DeployPath/$SetupFile" "tmaster:tdesktop/www/$RemoteFolder/"
|
||||||
|
fi
|
||||||
if [ "$BuildTarget" == "mac" ]; then
|
if [ "$BuildTarget" == "mac" ]; then
|
||||||
|
if [ "$DeployMac32" == "1" ]; then
|
||||||
scp "$Mac32DeployPath/$Mac32UpdateFile" "tmaster:tdesktop/www/$Mac32RemoteFolder/"
|
scp "$Mac32DeployPath/$Mac32UpdateFile" "tmaster:tdesktop/www/$Mac32RemoteFolder/"
|
||||||
scp "$Mac32DeployPath/$Mac32SetupFile" "tmaster:tdesktop/www/$Mac32RemoteFolder/"
|
scp "$Mac32DeployPath/$Mac32SetupFile" "tmaster:tdesktop/www/$Mac32RemoteFolder/"
|
||||||
|
fi
|
||||||
|
if [ "$DeployWin" == "1" ]; then
|
||||||
scp "$WinDeployPath/$WinUpdateFile" "tmaster:tdesktop/www/$WinRemoteFolder/"
|
scp "$WinDeployPath/$WinUpdateFile" "tmaster:tdesktop/www/$WinRemoteFolder/"
|
||||||
|
if [ "$BetaVersion" == "0" ]; then
|
||||||
scp "$WinDeployPath/$WinSetupFile" "tmaster:tdesktop/www/$WinRemoteFolder/"
|
scp "$WinDeployPath/$WinSetupFile" "tmaster:tdesktop/www/$WinRemoteFolder/"
|
||||||
|
fi
|
||||||
scp "$WinDeployPath/$WinPortableFile" "tmaster:tdesktop/www/$WinRemoteFolder/"
|
scp "$WinDeployPath/$WinPortableFile" "tmaster:tdesktop/www/$WinRemoteFolder/"
|
||||||
|
fi
|
||||||
|
|
||||||
mv -v "$WinDeployPath" "$DropboxPath/"
|
if [ "$DeployMac" == "1" ]; then
|
||||||
|
|
||||||
cp -v "$DeployPath/$UpdateFile" "$DropboxDeployPath/"
|
cp -v "$DeployPath/$UpdateFile" "$DropboxDeployPath/"
|
||||||
cp -v "$DeployPath/$SetupFile" "$DropboxDeployPath/"
|
cp -v "$DeployPath/$SetupFile" "$DropboxDeployPath/$DropboxSetupFile"
|
||||||
|
if [ -d "$DropboxDeployPath/Telegram.app.dSYM" ]; then
|
||||||
|
rm -rf "$DropboxDeployPath/Telegram.app.dSYM"
|
||||||
|
fi
|
||||||
cp -rv "$DeployPath/Telegram.app.dSYM" "$DropboxDeployPath/"
|
cp -rv "$DeployPath/Telegram.app.dSYM" "$DropboxDeployPath/"
|
||||||
cp -v "$Mac32DeployPath/$Mac32UpdateFile" "$DropboxDeployPath/"
|
fi
|
||||||
cp -v "$Mac32DeployPath/$Mac32SetupFile" "$DropboxDeployPath/"
|
if [ "$DeployMac32" == "1" ]; then
|
||||||
cp -rv "$DeployPath/Telegram.app.dSYM" "$DropboxDeployPath/Telegram32.app.dSYM"
|
mv -v "$Mac32DeployPath/$Mac32UpdateFile" "$DropboxDeployPath/"
|
||||||
|
mv -v "$Mac32DeployPath/$Mac32SetupFile" "$DropboxDeployPath/$DropboxMac32SetupFile"
|
||||||
|
if [ -d "$DropboxDeployPath/Telegram32.app.dSYM" ]; then
|
||||||
|
rm -rf "$DropboxDeployPath/Telegram32.app.dSYM"
|
||||||
|
fi
|
||||||
|
mv -v "$Mac32DeployPath/Telegram.app.dSYM" "$DropboxDeployPath/Telegram32.app.dSYM"
|
||||||
|
fi
|
||||||
|
if [ "$DeployWin" == "1" ]; then
|
||||||
|
mv -v "$WinDeployPath/Telegram.pdb" "$DropboxDeployPath/"
|
||||||
|
mv -v "$WinDeployPath/Updater.exe" "$DropboxDeployPath/"
|
||||||
|
mv -v "$WinDeployPath/Updater.pdb" "$DropboxDeployPath/"
|
||||||
|
mv -v "$WinDeployPath/$WinUpdateFile" "$DropboxDeployPath/"
|
||||||
|
if [ "$BetaVersion" == "0" ]; then
|
||||||
|
mv -v "$WinDeployPath/$WinSetupFile" "$DropboxDeployPath/"
|
||||||
|
fi
|
||||||
|
mv -v "$WinDeployPath/$WinPortableFile" "$DropboxDeployPath/"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -431,6 +431,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_channel_add_admins" = "New administrator";
|
"lng_channel_add_admins" = "New administrator";
|
||||||
"lng_channel_add_members" = "Add members";
|
"lng_channel_add_members" = "Add members";
|
||||||
"lng_channel_members" = "Members";
|
"lng_channel_members" = "Members";
|
||||||
|
"lng_channel_only_last_shown" = "Only the last {count:_not_used_|# member is|# members are} shown here";
|
||||||
"lng_channel_admins" = "Administrators";
|
"lng_channel_admins" = "Administrators";
|
||||||
"lng_channel_add_admin" = "Add Administrator";
|
"lng_channel_add_admin" = "Add Administrator";
|
||||||
"lng_channel_admin_sure" = "Add {user} to administrators?";
|
"lng_channel_admin_sure" = "Add {user} to administrators?";
|
||||||
|
@ -564,10 +565,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_emoji_category1" = "People";
|
"lng_emoji_category1" = "People";
|
||||||
"lng_emoji_category2" = "Nature";
|
"lng_emoji_category2" = "Nature";
|
||||||
"lng_emoji_category3" = "Food & Drink";
|
"lng_emoji_category3" = "Food & Drink";
|
||||||
"lng_emoji_category4" = "Celebration";
|
"lng_emoji_category4" = "Activity";
|
||||||
"lng_emoji_category5" = "Activity";
|
"lng_emoji_category5" = "Travel & Places";
|
||||||
"lng_emoji_category6" = "Travel & Places";
|
"lng_emoji_category6" = "Objects";
|
||||||
"lng_emoji_category7" = "Objects & Symbols";
|
"lng_emoji_category7" = "Symbols & Flags";
|
||||||
|
|
||||||
"lng_switch_stickers" = "Stickers";
|
"lng_switch_stickers" = "Stickers";
|
||||||
"lng_switch_emoji" = "Emoji";
|
"lng_switch_emoji" = "Emoji";
|
||||||
|
@ -581,6 +582,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_not_found" = "Sticker pack not found.";
|
"lng_stickers_not_found" = "Sticker pack not found.";
|
||||||
"lng_stickers_copied" = "Sticker pack link copied to clipboard.";
|
"lng_stickers_copied" = "Sticker pack link copied to clipboard.";
|
||||||
"lng_stickers_default_set" = "Great Minds";
|
"lng_stickers_default_set" = "Great Minds";
|
||||||
|
"lng_stickers_you_have" = "Manage and reorder sticker packs";
|
||||||
|
"lng_stickers_packs" = "Sticker Packs";
|
||||||
|
"lng_stickers_reorder" = "Click and drag to reorder sticker packs";
|
||||||
|
"lng_stickers_remove" = "Delete";
|
||||||
|
"lng_stickers_return" = "Undo";
|
||||||
|
"lng_stickers_restore" = "Restore";
|
||||||
|
"lng_stickers_count" = "{count:Loading..|# sticker|# stickers}";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "Photo";
|
"lng_in_dlg_photo" = "Photo";
|
||||||
"lng_in_dlg_video" = "Video";
|
"lng_in_dlg_video" = "Video";
|
||||||
|
@ -658,6 +666,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
"lng_choose_images" = "Choose images";
|
"lng_choose_images" = "Choose images";
|
||||||
|
|
||||||
|
"lng_context_view_profile" = "View profile";
|
||||||
|
"lng_context_view_group" = "View group info";
|
||||||
|
"lng_context_view_channel" = "View channel info";
|
||||||
|
|
||||||
"lng_context_open_link" = "Open Link";
|
"lng_context_open_link" = "Open Link";
|
||||||
"lng_context_copy_link" = "Copy Link";
|
"lng_context_copy_link" = "Copy Link";
|
||||||
"lng_context_open_email" = "Write to this address";
|
"lng_context_open_email" = "Write to this address";
|
||||||
|
@ -789,7 +801,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
||||||
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
||||||
"lng_new_version_text" = "— Groups can now have multiple administrators with the ability to edit the name and logo, and add and remove members\n— Groups that have reached their capacity of 200 users can be upgraded to supergroups of up to 1,000 members\n\nMore about admins and supergroups:\n{link}";
|
"lng_new_version_text" = "— Sticker management: manually rearrange your sticker packs, pack order is now synced across all your devices\n— Click and hold on a sticker to preview it before sending\n— New context menu for chats in chats list\n— Support for all existing emoji";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ titleBG: #6389a8;
|
||||||
titleColor: #0f8dcc;//rgb(20, 136, 210);
|
titleColor: #0f8dcc;//rgb(20, 136, 210);
|
||||||
titleHeight: 39px;
|
titleHeight: 39px;
|
||||||
titleIconPos: point(7px, 7px);
|
titleIconPos: point(7px, 7px);
|
||||||
titleIconImg: sprite(160px, 100px, 26px, 26px);
|
titleIconImg: sprite(161px, 100px, 26px, 26px);
|
||||||
titleFont: font(17px);
|
titleFont: font(17px);
|
||||||
titlePos: point(44px, 29px);
|
titlePos: point(44px, 29px);
|
||||||
titleMenuOffset: 36px;
|
titleMenuOffset: 36px;
|
||||||
|
@ -1424,12 +1424,13 @@ contactsNewItemIconPosition: point(29px, 19px);
|
||||||
contactsNewItemTop: 18px;
|
contactsNewItemTop: 18px;
|
||||||
contactsNewItemFg: #4b82af;
|
contactsNewItemFg: #4b82af;
|
||||||
contactsAboutBg: #f7f7f7;
|
contactsAboutBg: #f7f7f7;
|
||||||
|
contactsAboutShadow: #0000001F;
|
||||||
contactsAdminCheckbox: Checkbox(defaultCheckbox) {
|
contactsAdminCheckbox: Checkbox(defaultCheckbox) {
|
||||||
font: semiboldFont;
|
font: semiboldFont;
|
||||||
textBg: #f7f7f7;
|
textBg: #f7f7f7;
|
||||||
textPosition: point(34px, 1px);
|
textPosition: point(34px, 1px);
|
||||||
}
|
}
|
||||||
contactsAboutHeight: 80px;
|
contactsAboutHeight: 42px;
|
||||||
contactsAboutTop: 9px;
|
contactsAboutTop: 9px;
|
||||||
contactsScroll: flatScroll(boxScroll) {
|
contactsScroll: flatScroll(boxScroll) {
|
||||||
deltab: 0px;
|
deltab: 0px;
|
||||||
|
@ -1794,6 +1795,10 @@ stickersScroll: flatScroll(boxScroll) {
|
||||||
deltat: 23px;
|
deltat: 23px;
|
||||||
deltab: 9px;
|
deltab: 9px;
|
||||||
}
|
}
|
||||||
|
stickersReorderPadding: margins(0px, 12px, 0px, 12px);
|
||||||
|
stickersReorderFg: #777;
|
||||||
|
stickersRowDisabledOpacity: 0.4;
|
||||||
|
stickersRowDuration: 200;
|
||||||
|
|
||||||
emojiScroll: flatScroll(solidScroll) {
|
emojiScroll: flatScroll(solidScroll) {
|
||||||
deltat: 48px;
|
deltat: 48px;
|
||||||
|
@ -1806,14 +1811,15 @@ emojiNatureOver: sprite(42px, 196px, 21px, 22px);
|
||||||
emojiNatureActive: sprite(245px, 286px, 21px, 22px);
|
emojiNatureActive: sprite(245px, 286px, 21px, 22px);
|
||||||
emojiFoodOver: sprite(63px, 196px, 21px, 22px);
|
emojiFoodOver: sprite(63px, 196px, 21px, 22px);
|
||||||
emojiFoodActive: sprite(266px, 286px, 21px, 22px);
|
emojiFoodActive: sprite(266px, 286px, 21px, 22px);
|
||||||
emojiCelebrationOver: sprite(84px, 196px, 21px, 22px);
|
|
||||||
emojiCelebrationActive: sprite(287px, 286px, 21px, 22px);
|
|
||||||
emojiActivityOver: sprite(126px, 196px, 21px, 22px);
|
emojiActivityOver: sprite(126px, 196px, 21px, 22px);
|
||||||
emojiActivityActive: sprite(287px, 264px, 21px, 22px);
|
emojiActivityActive: sprite(287px, 264px, 21px, 22px);
|
||||||
emojiTravelOver: sprite(105px, 196px, 21px, 22px);
|
emojiTravelOver: sprite(105px, 196px, 21px, 22px);
|
||||||
emojiTravelActive: sprite(308px, 286px, 21px, 22px);
|
emojiTravelActive: sprite(308px, 286px, 21px, 22px);
|
||||||
emojiObjectsOver: sprite(147px, 196px, 21px, 22px);
|
emojiObjectsOver: sprite(147px, 196px, 21px, 22px);
|
||||||
emojiObjectsActive: sprite(308px, 264px, 21px, 22px);
|
emojiObjectsActive: sprite(308px, 264px, 21px, 22px);
|
||||||
|
emojiSymbolsOver: sprite(84px, 196px, 21px, 22px);
|
||||||
|
emojiSymbolsActive: sprite(287px, 286px, 21px, 22px);
|
||||||
|
stickersSettings: sprite(140px, 124px, 21px, 22px);
|
||||||
|
|
||||||
emojiPanCategories: #f7f7f7;
|
emojiPanCategories: #f7f7f7;
|
||||||
|
|
||||||
|
@ -1867,14 +1873,6 @@ rbEmojiFood: flatCheckbox(rbEmoji) {
|
||||||
disImageRect: emojiFoodOver;
|
disImageRect: emojiFoodOver;
|
||||||
chkDisImageRect: emojiFoodActive;
|
chkDisImageRect: emojiFoodActive;
|
||||||
}
|
}
|
||||||
rbEmojiCelebration: flatCheckbox(rbEmoji) {
|
|
||||||
imageRect: emojiCelebrationOver;
|
|
||||||
chkImageRect: emojiCelebrationActive;
|
|
||||||
overImageRect: emojiCelebrationOver;
|
|
||||||
chkOverImageRect: emojiCelebrationActive;
|
|
||||||
disImageRect: emojiCelebrationOver;
|
|
||||||
chkDisImageRect: emojiCelebrationActive;
|
|
||||||
}
|
|
||||||
rbEmojiActivity: flatCheckbox(rbEmoji) {
|
rbEmojiActivity: flatCheckbox(rbEmoji) {
|
||||||
imageRect: emojiActivityOver;
|
imageRect: emojiActivityOver;
|
||||||
chkImageRect: emojiActivityActive;
|
chkImageRect: emojiActivityActive;
|
||||||
|
@ -1899,6 +1897,14 @@ rbEmojiObjects: flatCheckbox(rbEmoji) {
|
||||||
disImageRect: emojiObjectsOver;
|
disImageRect: emojiObjectsOver;
|
||||||
chkDisImageRect: emojiObjectsActive;
|
chkDisImageRect: emojiObjectsActive;
|
||||||
}
|
}
|
||||||
|
rbEmojiSymbols: flatCheckbox(rbEmoji) {
|
||||||
|
imageRect: emojiSymbolsOver;
|
||||||
|
chkImageRect: emojiSymbolsActive;
|
||||||
|
overImageRect: emojiSymbolsOver;
|
||||||
|
chkOverImageRect: emojiSymbolsActive;
|
||||||
|
disImageRect: emojiSymbolsOver;
|
||||||
|
chkDisImageRect: emojiSymbolsActive;
|
||||||
|
}
|
||||||
emojiPanPadding: 12px;
|
emojiPanPadding: 12px;
|
||||||
emojiPanSize: size(45px, 41px);
|
emojiPanSize: size(45px, 41px);
|
||||||
emojiPanWidth: 345px;
|
emojiPanWidth: 345px;
|
||||||
|
@ -1934,12 +1940,15 @@ stickerIconSelColor: #58b2ed;
|
||||||
stickerIconLeft: sprite(342px, 72px, 40px, 1px);
|
stickerIconLeft: sprite(342px, 72px, 40px, 1px);
|
||||||
stickerIconRight: sprite(342px, 73px, 40px, 1px);
|
stickerIconRight: sprite(342px, 73px, 40px, 1px);
|
||||||
stickerIconMove: 400;
|
stickerIconMove: 400;
|
||||||
|
stickerPreviewDuration: 150;
|
||||||
|
stickerPreviewBg: #FFFFFFB0;
|
||||||
|
stickerPreviewMin: 0.1;
|
||||||
|
|
||||||
verifiedCheckProfile: sprite(285px, 240px, 22px, 22px);
|
verifiedCheckProfile: sprite(285px, 235px, 18px, 18px);
|
||||||
verifiedCheckProfilePos: point(9px, 4px);
|
verifiedCheckProfilePos: point(7px, 6px);
|
||||||
verifiedCheck: sprite(285px, 221px, 19px, 19px);
|
verifiedCheck: sprite(285px, 221px, 14px, 14px);
|
||||||
verifiedCheckInv: sprite(304px, 221px, 19px, 19px);
|
verifiedCheckInv: sprite(299px, 221px, 14px, 14px);
|
||||||
verifiedCheckPos: point(5px, 0px);
|
verifiedCheckPos: point(4px, 2px);
|
||||||
|
|
||||||
botKbDuration: 200;
|
botKbDuration: 200;
|
||||||
botKbBg: #f7f7f7;
|
botKbBg: #f7f7f7;
|
||||||
|
|
|
@ -36,8 +36,9 @@ Q_IMPORT_PLUGIN(QWebpPlugin)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool DevChannel = false;
|
bool DevChannel = false;
|
||||||
|
quint64 BetaVersion = 0;
|
||||||
|
|
||||||
const char *publicKey = "\
|
const char *PublicKey = "\
|
||||||
-----BEGIN RSA PUBLIC KEY-----\n\
|
-----BEGIN RSA PUBLIC KEY-----\n\
|
||||||
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
|
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
|
||||||
BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
|
BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
|
||||||
|
@ -45,7 +46,7 @@ BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
|
||||||
-----END RSA PUBLIC KEY-----\
|
-----END RSA PUBLIC KEY-----\
|
||||||
";
|
";
|
||||||
|
|
||||||
const char *publicDevKey = "\
|
const char *PublicDevKey = "\
|
||||||
-----BEGIN RSA PUBLIC KEY-----\n\
|
-----BEGIN RSA PUBLIC KEY-----\n\
|
||||||
MIGJAoGBALWu9GGs0HED7KG7BM73CFZ6o0xufKBRQsdnq3lwA8nFQEvmdu+g/I1j\n\
|
MIGJAoGBALWu9GGs0HED7KG7BM73CFZ6o0xufKBRQsdnq3lwA8nFQEvmdu+g/I1j\n\
|
||||||
0LQ+0IQO7GW4jAgzF/4+soPDb6uHQeNFrlVx1JS9DZGhhjZ5rf65yg11nTCIHZCG\n\
|
0LQ+0IQO7GW4jAgzF/4+soPDb6uHQeNFrlVx1JS9DZGhhjZ5rf65yg11nTCIHZCG\n\
|
||||||
|
@ -53,9 +54,12 @@ w/CVnbwQOw0g5GBwwFV3r0uTTvy44xx8XXxk+Qknu4eBCsmrAFNnAgMBAAE=\n\
|
||||||
-----END RSA PUBLIC KEY-----\
|
-----END RSA PUBLIC KEY-----\
|
||||||
";
|
";
|
||||||
|
|
||||||
extern const char *privateKey;
|
extern const char *PrivateKey;
|
||||||
extern const char *privateDevKey;
|
extern const char *PrivateDevKey;
|
||||||
#include "../../../../TelegramPrivate/packer_private.h" // RSA PRIVATE KEYS for update signing
|
#include "../../../../TelegramPrivate/packer_private.h" // RSA PRIVATE KEYS for update signing
|
||||||
|
#include "../../../../TelegramPrivate/beta_private.h" // private key for beta version file generation
|
||||||
|
|
||||||
|
QString countBetaVersionSignature(quint64 version);
|
||||||
|
|
||||||
// sha1 hash
|
// sha1 hash
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
|
@ -138,6 +142,8 @@ int32 *hashSha1(const void *data, uint32 len, void *dest) {
|
||||||
return (int32*)sha1To;
|
return (int32*)sha1To;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString BetaSignature;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QString workDir;
|
QString workDir;
|
||||||
|
@ -167,14 +173,28 @@ int main(int argc, char *argv[])
|
||||||
version = QString(argv[i + 1]).toInt();
|
version = QString(argv[i + 1]).toInt();
|
||||||
} else if (string("-dev") == argv[i]) {
|
} else if (string("-dev") == argv[i]) {
|
||||||
DevChannel = true;
|
DevChannel = true;
|
||||||
|
} else if (string("-beta") == argv[i] && i + 1 < argc) {
|
||||||
|
BetaVersion = QString(argv[i + 1]).toULongLong();
|
||||||
|
if (BetaVersion > version * 1000ULL && BetaVersion < (version + 1) * 1000ULL) {
|
||||||
|
DevChannel = false;
|
||||||
|
BetaSignature = countBetaVersionSignature(BetaVersion);
|
||||||
|
if (BetaSignature.isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cout << "Bad -beta param value passed, should be for the same version: " << version << ", beta: " << BetaVersion << "\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (files.isEmpty() || remove.isEmpty() || version <= 1016 || version > 999999) { // not for release =)
|
if (files.isEmpty() || remove.isEmpty() || version <= 1016 || version > 999999999) {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
cout << "Usage: Packer.exe -path {file} -version {version} OR Packer.exe -path {dir} -version {version}\n";
|
cout << "Usage: Packer.exe -path {file} -version {version} OR Packer.exe -path {dir} -version {version}\n";
|
||||||
#elif defined Q_OS_MAC
|
#elif defined Q_OS_MAC
|
||||||
cout << "Usage: Packer.app -path {file} -version {version} OR Packer.app -path {dir} -version {version}\n";
|
cout << "Usage: Packer.app -path {file} -version {version} OR Packer.app -path {dir} -version {version}\n";
|
||||||
|
#else
|
||||||
|
cout << "Usage: Packer -path {file} -version {version} OR Packer -path {dir} -version {version}\n";
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +238,12 @@ int main(int argc, char *argv[])
|
||||||
QDataStream stream(&buffer);
|
QDataStream stream(&buffer);
|
||||||
stream.setVersion(QDataStream::Qt_5_1);
|
stream.setVersion(QDataStream::Qt_5_1);
|
||||||
|
|
||||||
|
if (BetaVersion) {
|
||||||
|
stream << quint32(0x7FFFFFFF);
|
||||||
|
stream << quint64(BetaVersion);
|
||||||
|
} else {
|
||||||
stream << quint32(version);
|
stream << quint32(version);
|
||||||
|
}
|
||||||
|
|
||||||
stream << quint32(files.size());
|
stream << quint32(files.size());
|
||||||
cout << "Found " << files.size() << " file" << (files.size() == 1 ? "" : "s") << "..\n";
|
cout << "Found " << files.size() << " file" << (files.size() == 1 ? "" : "s") << "..\n";
|
||||||
|
@ -409,19 +434,19 @@ int main(int argc, char *argv[])
|
||||||
uint32 siglen = 0;
|
uint32 siglen = 0;
|
||||||
|
|
||||||
cout << "Signing..\n";
|
cout << "Signing..\n";
|
||||||
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(DevChannel ? privateDevKey : privateKey), -1), 0, 0, 0);
|
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>((DevChannel || BetaVersion) ? PrivateDevKey : PrivateKey), -1), 0, 0, 0);
|
||||||
if (!prKey) {
|
if (!prKey) {
|
||||||
cout << "Could not read RSA private key!\n";
|
cout << "Could not read RSA private key!\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (RSA_size(prKey) != hSigLen) {
|
if (RSA_size(prKey) != hSigLen) {
|
||||||
RSA_free(prKey);
|
|
||||||
cout << "Bad private key, size: " << RSA_size(prKey) << "\n";
|
cout << "Bad private key, size: " << RSA_size(prKey) << "\n";
|
||||||
|
RSA_free(prKey);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (RSA_sign(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (uchar*)(compressed.data()), &siglen, prKey) != 1) { // count signature
|
if (RSA_sign(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (uchar*)(compressed.data()), &siglen, prKey) != 1) { // count signature
|
||||||
RSA_free(prKey);
|
|
||||||
cout << "Signing failed!\n";
|
cout << "Signing failed!\n";
|
||||||
|
RSA_free(prKey);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
RSA_free(prKey);
|
RSA_free(prKey);
|
||||||
|
@ -432,7 +457,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "Checking signature..\n";
|
cout << "Checking signature..\n";
|
||||||
RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(DevChannel ? publicDevKey : publicKey), -1), 0, 0, 0);
|
RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>((DevChannel || BetaVersion) ? PublicDevKey : PublicKey), -1), 0, 0, 0);
|
||||||
if (!pbKey) {
|
if (!pbKey) {
|
||||||
cout << "Could not read RSA public key!\n";
|
cout << "Could not read RSA public key!\n";
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -445,16 +470,19 @@ int main(int argc, char *argv[])
|
||||||
cout << "Signature verified!\n";
|
cout << "Signature verified!\n";
|
||||||
RSA_free(pbKey);
|
RSA_free(pbKey);
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QString outName(QString("tupdate%1").arg(version));
|
QString outName(QString("tupdate%1").arg(BetaVersion ? BetaVersion : version));
|
||||||
#elif defined Q_OS_MAC
|
#elif defined Q_OS_MAC
|
||||||
QString outName(QString("tmacupd%1").arg(version));
|
QString outName(QString("tmacupd%1").arg(BetaVersion ? BetaVersion : version));
|
||||||
#elif defined Q_OS_LINUX32
|
#elif defined Q_OS_LINUX32
|
||||||
QString outName(QString("tlinux32upd%1").arg(version));
|
QString outName(QString("tlinux32upd%1").arg(BetaVersion ? BetaVersion : version));
|
||||||
#elif defined Q_OS_LINUX64
|
#elif defined Q_OS_LINUX64
|
||||||
QString outName(QString("tlinuxupd%1").arg(version));
|
QString outName(QString("tlinuxupd%1").arg(BetaVersion ? BetaVersion : version));
|
||||||
#else
|
#else
|
||||||
#error Unknown platform!
|
#error Unknown platform!
|
||||||
#endif
|
#endif
|
||||||
|
if (BetaVersion) {
|
||||||
|
outName += "_" + BetaSignature;
|
||||||
|
}
|
||||||
QFile out(outName);
|
QFile out(outName);
|
||||||
if (!out.open(QIODevice::WriteOnly)) {
|
if (!out.open(QIODevice::WriteOnly)) {
|
||||||
cout << "Can't open '" << outName.toUtf8().constData() << "' for write..\n";
|
cout << "Can't open '" << outName.toUtf8().constData() << "' for write..\n";
|
||||||
|
@ -463,7 +491,63 @@ int main(int argc, char *argv[])
|
||||||
out.write(compressed);
|
out.write(compressed);
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
|
if (BetaVersion) {
|
||||||
|
QString keyName(QString("tbeta_%1_key").arg(BetaVersion));
|
||||||
|
QFile key(keyName);
|
||||||
|
if (!key.open(QIODevice::WriteOnly)) {
|
||||||
|
cout << "Can't open '" << keyName.toUtf8().constData() << "' for write..\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
key.write(BetaSignature.toUtf8());
|
||||||
|
key.close();
|
||||||
|
}
|
||||||
|
|
||||||
cout << "Update file '" << outName.toUtf8().constData() << "' written successfully!\n";
|
cout << "Update file '" << outName.toUtf8().constData() << "' written successfully!\n";
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString countBetaVersionSignature(quint64 version) { // duplicated in autoupdate.cpp
|
||||||
|
QByteArray cBetaPrivateKey(BetaPrivateKey);
|
||||||
|
if (cBetaPrivateKey.isEmpty()) {
|
||||||
|
cout << "Error: Trying to count beta version signature without beta private key!\n";
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray signedData = (QLatin1String("TelegramBeta_") + QString::number(version, 16).toLower()).toUtf8();
|
||||||
|
|
||||||
|
static const int32 shaSize = 20, keySize = 128;
|
||||||
|
|
||||||
|
uchar sha1Buffer[shaSize];
|
||||||
|
hashSha1(signedData.constData(), signedData.size(), sha1Buffer); // count sha1
|
||||||
|
|
||||||
|
uint32 siglen = 0;
|
||||||
|
|
||||||
|
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(cBetaPrivateKey.constData()), -1), 0, 0, 0);
|
||||||
|
if (!prKey) {
|
||||||
|
cout << "Error: Could not read beta private key!\n";
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
if (RSA_size(prKey) != keySize) {
|
||||||
|
cout << "Error: Bad beta private key size: " << RSA_size(prKey) << "\n";
|
||||||
|
RSA_free(prKey);
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
QByteArray signature;
|
||||||
|
signature.resize(keySize);
|
||||||
|
if (RSA_sign(NID_sha1, (const uchar*)(sha1Buffer), shaSize, (uchar*)(signature.data()), &siglen, prKey) != 1) { // count signature
|
||||||
|
cout << "Error: Counting beta version signature failed!\n";
|
||||||
|
RSA_free(prKey);
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
RSA_free(prKey);
|
||||||
|
|
||||||
|
if (siglen != keySize) {
|
||||||
|
cout << "Error: Bad beta version signature length: " << siglen << "\n";
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
signature = signature.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
signature = signature.replace('-', '8').replace('_', 'B');
|
||||||
|
return QString::fromUtf8(signature.mid(19, 32));
|
||||||
|
}
|
||||||
|
|
|
@ -148,11 +148,15 @@ bool update() {
|
||||||
if (versionFile != INVALID_HANDLE_VALUE) {
|
if (versionFile != INVALID_HANDLE_VALUE) {
|
||||||
if (!ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD)) {
|
if (!ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD)) {
|
||||||
versionNum = 0;
|
versionNum = 0;
|
||||||
|
} else {
|
||||||
|
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||||
|
|
||||||
} else if (!ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD) || versionLen > 63) {
|
} else if (!ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD) || versionLen > 63) {
|
||||||
versionNum = 0;
|
versionNum = 0;
|
||||||
} else if (!ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) || readLen != versionLen) {
|
} else if (!ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) || readLen != versionLen) {
|
||||||
versionNum = 0;
|
versionNum = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
CloseHandle(versionFile);
|
CloseHandle(versionFile);
|
||||||
writeLog(L"Version file read.");
|
writeLog(L"Version file read.");
|
||||||
} else {
|
} else {
|
||||||
|
@ -270,7 +274,7 @@ bool update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateRegistry() {
|
void updateRegistry() {
|
||||||
if (versionNum) {
|
if (versionNum && versionNum != 0x7FFFFFFF) {
|
||||||
writeLog(L"Updating registry..");
|
writeLog(L"Updating registry..");
|
||||||
versionStr[versionLen / 2] = 0;
|
versionStr[versionLen / 2] = 0;
|
||||||
HKEY rkey;
|
HKEY rkey;
|
||||||
|
|
|
@ -726,29 +726,19 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
|
||||||
it->access = s.vaccess_hash.v;
|
it->access = s.vaccess_hash.v;
|
||||||
it->hash = s.vhash.v;
|
it->hash = s.vhash.v;
|
||||||
it->shortName = qs(s.vshort_name);
|
it->shortName = qs(s.vshort_name);
|
||||||
QString title = qs(s.vtitle);
|
it->title = stickerSetTitle(s);
|
||||||
if ((it->flags & MTPDstickerSet::flag_official) && !title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) {
|
|
||||||
title = lang(lng_stickers_default_set);
|
|
||||||
}
|
|
||||||
it->title = title;
|
|
||||||
it->flags = s.vflags.v;
|
it->flags = s.vflags.v;
|
||||||
|
|
||||||
const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v);
|
const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v);
|
||||||
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
||||||
|
|
||||||
QSet<DocumentData*> found;
|
StickerPack pack;
|
||||||
int32 wasCount = -1;
|
pack.reserve(d_docs.size());
|
||||||
for (int32 i = 0, l = d_docs.size(); i != l; ++i) {
|
for (int32 i = 0, l = d_docs.size(); i != l; ++i) {
|
||||||
DocumentData *doc = App::feedDocument(d_docs.at(i));
|
DocumentData *doc = App::feedDocument(d_docs.at(i));
|
||||||
if (!doc || !doc->sticker()) continue;
|
if (!doc || !doc->sticker()) continue;
|
||||||
|
|
||||||
if (wasCount < 0) wasCount = it->stickers.size();
|
pack.push_back(doc);
|
||||||
if (it->stickers.indexOf(doc) < 0) {
|
|
||||||
it->stickers.push_back(doc);
|
|
||||||
} else {
|
|
||||||
found.insert(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (custom != sets.cend()) {
|
if (custom != sets.cend()) {
|
||||||
int32 index = custom->stickers.indexOf(doc);
|
int32 index = custom->stickers.indexOf(doc);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@ -763,39 +753,20 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
|
||||||
|
|
||||||
bool writeRecent = false;
|
bool writeRecent = false;
|
||||||
RecentStickerPack &recent(cGetRecentStickers());
|
RecentStickerPack &recent(cGetRecentStickers());
|
||||||
|
|
||||||
if (wasCount < 0) { // no stickers received
|
|
||||||
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
||||||
if (it->stickers.indexOf(i->first) >= 0) {
|
if (it->stickers.indexOf(i->first) >= 0 && pack.indexOf(i->first) < 0) {
|
||||||
i = recent.erase(i);
|
i = recent.erase(i);
|
||||||
writeRecent = true;
|
writeRecent = true;
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cRefStickerSetsOrder().removeOne(setId);
|
if (pack.isEmpty()) {
|
||||||
|
int32 removeIndex = cStickerSetsOrder().indexOf(setId);
|
||||||
|
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
|
||||||
sets.erase(it);
|
sets.erase(it);
|
||||||
} else {
|
} else {
|
||||||
for (int32 j = 0, l = wasCount; j < l;) {
|
it->stickers = pack;
|
||||||
if (found.contains(it->stickers.at(j))) {
|
|
||||||
++j;
|
|
||||||
} else {
|
|
||||||
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
|
||||||
if (it->stickers.at(j) == i->first) {
|
|
||||||
i = recent.erase(i);
|
|
||||||
writeRecent = true;
|
|
||||||
} else {
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
it->stickers.removeAt(j);
|
|
||||||
--l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (it->stickers.isEmpty()) {
|
|
||||||
cRefStickerSetsOrder().removeOne(setId);
|
|
||||||
sets.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeRecent) {
|
if (writeRecent) {
|
||||||
|
|
|
@ -1632,8 +1632,9 @@ namespace App {
|
||||||
convert->sticker()->loc = thumbLocation;
|
convert->sticker()->loc = thumbLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convert->location.check()) {
|
const FileLocation &loc(convert->location(true));
|
||||||
Local::writeFileLocation(mediaKey(DocumentFileLocation, convert->dc, convert->id), convert->location);
|
if (!loc.isEmpty()) {
|
||||||
|
Local::writeFileLocation(mediaKey(DocumentFileLocation, convert->dc, convert->id), loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DocumentsData::const_iterator i = documentsData.constFind(document);
|
DocumentsData::const_iterator i = documentsData.constFind(document);
|
||||||
|
@ -1984,7 +1985,7 @@ namespace App {
|
||||||
webPagesData.clear();
|
webPagesData.clear();
|
||||||
if (api()) api()->clearWebPageRequests();
|
if (api()) api()->clearWebPageRequests();
|
||||||
cSetRecentStickers(RecentStickerPack());
|
cSetRecentStickers(RecentStickerPack());
|
||||||
cSetStickersHash(QByteArray());
|
cSetStickersHash(0);
|
||||||
cSetStickerSets(StickerSets());
|
cSetStickerSets(StickerSets());
|
||||||
cSetStickerSetsOrder(StickerSetsOrder());
|
cSetStickerSetsOrder(StickerSetsOrder());
|
||||||
cSetLastStickersUpdate(0);
|
cSetLastStickersUpdate(0);
|
||||||
|
@ -2804,79 +2805,4 @@ namespace App {
|
||||||
|
|
||||||
WallPapers gServerBackgrounds;
|
WallPapers gServerBackgrounds;
|
||||||
|
|
||||||
void sendBotCommand(const QString &cmd, MsgId replyTo) {
|
|
||||||
if (MainWidget *m = main()) m->sendBotCommand(cmd, replyTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void insertBotCommand(const QString &cmd) {
|
|
||||||
if (MainWidget *m = main()) m->insertBotCommand(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
|
||||||
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void openPeerByName(const QString &username, bool toProfile, const QString &startToken) {
|
|
||||||
if (MainWidget *m = main()) m->openPeerByName(username, toProfile, startToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
void joinGroupByHash(const QString &hash) {
|
|
||||||
if (MainWidget *m = main()) m->joinGroupByHash(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stickersBox(const QString &name) {
|
|
||||||
if (MainWidget *m = main()) m->stickersBox(MTP_inputStickerSetShortName(MTP_string(name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void openLocalUrl(const QString &url) {
|
|
||||||
if (MainWidget *m = main()) m->openLocalUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool forward(const PeerId &peer, ForwardWhatMessages what) {
|
|
||||||
if (MainWidget *m = main()) return m->onForward(peer, what);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeDialog(History *history) {
|
|
||||||
if (MainWidget *m = main()) m->removeDialog(history);
|
|
||||||
}
|
|
||||||
|
|
||||||
void showSettings() {
|
|
||||||
if (Window *win = wnd()) win->showSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void showLayer(LayeredWidget *w, bool forceFast) {
|
|
||||||
if (Window *win = wnd()) win->showLayer(w, forceFast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void replaceLayer(LayeredWidget *w) {
|
|
||||||
if (Window *win = wnd()) win->replaceLayer(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
void showLayerLast(LayeredWidget *w) {
|
|
||||||
if (Window *win = wnd()) win->showLayerLast(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Notify {
|
|
||||||
|
|
||||||
void userIsBotChanged(UserData *user) {
|
|
||||||
if (MainWidget *m = App::main()) {
|
|
||||||
m->notifyUserIsBotChanged(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void botCommandsChanged(UserData *user) {
|
|
||||||
if (MainWidget *m = App::main()) {
|
|
||||||
m->notifyBotCommandsChanged(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void migrateUpdated(PeerData *peer) {
|
|
||||||
if (MainWidget *m = App::main()) {
|
|
||||||
m->notifyMigrateUpdated(peer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,13 +80,6 @@ enum RoundCorners {
|
||||||
RoundCornersCount
|
RoundCornersCount
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ForwardWhatMessages {
|
|
||||||
ForwardSelectedMessages,
|
|
||||||
ForwardContextMessage,
|
|
||||||
ForwardPressedMessage,
|
|
||||||
ForwardPressedLinkMessage
|
|
||||||
};
|
|
||||||
|
|
||||||
class LayeredWidget;
|
class LayeredWidget;
|
||||||
|
|
||||||
namespace App {
|
namespace App {
|
||||||
|
@ -300,26 +293,27 @@ namespace App {
|
||||||
typedef QList<WallPaper> WallPapers;
|
typedef QList<WallPaper> WallPapers;
|
||||||
DeclareSetting(WallPapers, ServerBackgrounds);
|
DeclareSetting(WallPapers, ServerBackgrounds);
|
||||||
|
|
||||||
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
|
||||||
void insertBotCommand(const QString &cmd);
|
|
||||||
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
|
||||||
void openPeerByName(const QString &username, bool toProfile = false, const QString &startToken = QString());
|
|
||||||
void joinGroupByHash(const QString &hash);
|
|
||||||
void stickersBox(const QString &name);
|
|
||||||
void openLocalUrl(const QString &url);
|
|
||||||
bool forward(const PeerId &peer, ForwardWhatMessages what);
|
|
||||||
void removeDialog(History *history);
|
|
||||||
void showSettings();
|
|
||||||
void showLayer(LayeredWidget *w, bool forceFast = false);
|
|
||||||
void replaceLayer(LayeredWidget *w);
|
|
||||||
void showLayerLast(LayeredWidget *w);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Notify {
|
inline int32 stickersCountHash(bool checkOfficial = false) {
|
||||||
|
uint32 acc = 0;
|
||||||
|
bool foundOfficial = false, foundBad = false;;
|
||||||
|
const StickerSets &sets(cStickerSets());
|
||||||
|
const StickerSetsOrder &order(cStickerSetsOrder());
|
||||||
|
for (StickerSetsOrder::const_iterator i = order.cbegin(), e = order.cend(); i != e; ++i) {
|
||||||
|
StickerSets::const_iterator j = sets.constFind(*i);
|
||||||
|
if (j != sets.cend()) {
|
||||||
|
if (j->id == 0) {
|
||||||
|
foundBad = true;
|
||||||
|
} else if (j->flags & MTPDstickerSet::flag_official) {
|
||||||
|
foundOfficial = true;
|
||||||
|
}
|
||||||
|
if (!(j->flags & MTPDstickerSet::flag_disabled)) {
|
||||||
|
acc = (acc * 20261) + j->hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (!checkOfficial || (!foundBad && foundOfficial)) ? int32(acc & 0x7FFFFFFF) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void userIsBotChanged(UserData *user);
|
#include "facades.h"
|
||||||
void botCommandsChanged(UserData *user);
|
|
||||||
void migrateUpdated(PeerData *peer);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace {
|
||||||
bool eventFilter(QObject *o, QEvent *e) {
|
bool eventFilter(QObject *o, QEvent *e) {
|
||||||
if (e->type() == QEvent::KeyPress) {
|
if (e->type() == QEvent::KeyPress) {
|
||||||
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
|
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
|
||||||
if (cPlatform() == dbipMac) {
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
if (ev->key() == Qt::Key_W && (ev->modifiers() & Qt::ControlModifier)) {
|
if (ev->key() == Qt::Key_W && (ev->modifiers() & Qt::ControlModifier)) {
|
||||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||||
App::wnd()->minimizeToTray();
|
App::wnd()->minimizeToTray();
|
||||||
|
@ -210,11 +210,17 @@ void Application::updateGotCurrent() {
|
||||||
cSetLastUpdateCheck(unixtime());
|
cSetLastUpdateCheck(unixtime());
|
||||||
QRegularExpressionMatch m = QRegularExpression(qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")).match(QString::fromUtf8(updateReply->readAll()));
|
QRegularExpressionMatch m = QRegularExpression(qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")).match(QString::fromUtf8(updateReply->readAll()));
|
||||||
if (m.hasMatch()) {
|
if (m.hasMatch()) {
|
||||||
int32 currentVersion = m.captured(1).toInt();
|
uint64 currentVersion = m.captured(1).toULongLong();
|
||||||
if (currentVersion > AppVersion) {
|
QString url = m.captured(2);
|
||||||
|
bool betaVersion = false;
|
||||||
|
if (url.startsWith(qstr("beta_"))) {
|
||||||
|
betaVersion = true;
|
||||||
|
url = url.mid(5) + '_' + countBetaVersionSignature(currentVersion);
|
||||||
|
}
|
||||||
|
if ((!betaVersion || cBetaVersion()) && currentVersion > (betaVersion ? cBetaVersion() : uint64(AppVersion))) {
|
||||||
updateThread = new QThread();
|
updateThread = new QThread();
|
||||||
connect(updateThread, SIGNAL(finished()), updateThread, SLOT(deleteLater()));
|
connect(updateThread, SIGNAL(finished()), updateThread, SLOT(deleteLater()));
|
||||||
updateDownloader = new UpdateDownloader(updateThread, m.captured(2));
|
updateDownloader = new UpdateDownloader(updateThread, url);
|
||||||
updateThread->start();
|
updateThread->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +231,7 @@ void Application::updateGotCurrent() {
|
||||||
if (updates.exists()) {
|
if (updates.exists()) {
|
||||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||||
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||||
QFile(i->absoluteFilePath()).remove();
|
QFile(i->absoluteFilePath()).remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -543,14 +549,15 @@ void Application::startUpdateCheck(bool forceWait) {
|
||||||
updateCheckTimer.stop();
|
updateCheckTimer.stop();
|
||||||
if (updateRequestId || updateThread || updateReply || !cAutoUpdate()) return;
|
if (updateRequestId || updateThread || updateReply || !cAutoUpdate()) return;
|
||||||
|
|
||||||
int32 updateInSecs = cLastUpdateCheck() + UpdateDelayConstPart + (rand() % UpdateDelayRandPart) - unixtime();
|
int32 constDelay = cBetaVersion() ? 600 : UpdateDelayConstPart, randDelay = cBetaVersion() ? 300 : UpdateDelayRandPart;
|
||||||
bool sendRequest = (updateInSecs <= 0 || updateInSecs > (UpdateDelayConstPart + UpdateDelayRandPart));
|
int32 updateInSecs = cLastUpdateCheck() + constDelay + (rand() % randDelay) - unixtime();
|
||||||
|
bool sendRequest = (updateInSecs <= 0 || updateInSecs > (constDelay + randDelay));
|
||||||
if (!sendRequest && !forceWait) {
|
if (!sendRequest && !forceWait) {
|
||||||
QDir updates(cWorkingDir() + "tupdates");
|
QDir updates(cWorkingDir() + "tupdates");
|
||||||
if (updates.exists()) {
|
if (updates.exists()) {
|
||||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||||
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||||
sendRequest = true;
|
sendRequest = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +567,9 @@ void Application::startUpdateCheck(bool forceWait) {
|
||||||
|
|
||||||
if (sendRequest) {
|
if (sendRequest) {
|
||||||
QUrl url(cUpdateURL());
|
QUrl url(cUpdateURL());
|
||||||
if (cDevVersion()) {
|
if (cBetaVersion()) {
|
||||||
|
url.setQuery(qsl("version=%1&beta=%2").arg(AppVersion).arg(cBetaVersion()));
|
||||||
|
} else if (cDevVersion()) {
|
||||||
url.setQuery(qsl("version=%1&dev=1").arg(AppVersion));
|
url.setQuery(qsl("version=%1&dev=1").arg(AppVersion));
|
||||||
} else {
|
} else {
|
||||||
url.setQuery(qsl("version=%1").arg(AppVersion));
|
url.setQuery(qsl("version=%1").arg(AppVersion));
|
||||||
|
@ -696,10 +705,10 @@ void Application::checkMapVersion() {
|
||||||
if (Local::oldMapVersion() < AppVersion) {
|
if (Local::oldMapVersion() < AppVersion) {
|
||||||
if (Local::oldMapVersion()) {
|
if (Local::oldMapVersion()) {
|
||||||
QString versionFeatures;
|
QString versionFeatures;
|
||||||
if (cDevVersion() && Local::oldMapVersion() < 9011) {
|
if (cDevVersion() && Local::oldMapVersion() < 9014) {
|
||||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Groups can now have multiple administrators with the ability to edit the name and logo, and add and remove members.\n\xe2\x80\x94 Groups that have reached their capacity of 200 users can be upgraded to supergroups of up to 1,000 members.\n\nWARNING: Only updated Telegram apps will be able to open supergroups. DO NOT upgrade your groups before the stable version is out and updates for other apps are released.");// .replace('@', qsl("@") + QChar(0x200D));
|
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Sticker management: manually rearrange your sticker packs, pack order is now synced across all your devices\n\xe2\x80\x94 Click and hold on a sticker to preview it before sending\n\xe2\x80\x94 New context menu for chats in chats list\n\xe2\x80\x94 Support for all existing emoji");// .replace('@', qsl("@") + QChar(0x200D));
|
||||||
} else if (Local::oldMapVersion() < 9013) {
|
} else if (Local::oldMapVersion() < 9015) {
|
||||||
versionFeatures = lng_new_version_text(lt_link, qsl("https://telegram.org/blog/supergroups")).trimmed();
|
versionFeatures = lang(lng_new_version_text).trimmed();
|
||||||
} else {
|
} else {
|
||||||
versionFeatures = lang(lng_new_version_minor).trimmed();
|
versionFeatures = lang(lng_new_version_minor).trimmed();
|
||||||
}
|
}
|
||||||
|
@ -709,6 +718,9 @@ void Application::checkMapVersion() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cNeedConfigResave()) {
|
||||||
|
Local::writeUserSettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::startApp() {
|
void Application::startApp() {
|
||||||
|
|
Before Width: | Height: | Size: 586 KiB After Width: | Height: | Size: 762 KiB |
Before Width: | Height: | Size: 789 KiB After Width: | Height: | Size: 1 MiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 240 KiB |
|
@ -270,7 +270,7 @@ void audioFinish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioPlayer::Msg::clearData() {
|
void AudioPlayer::Msg::clearData() {
|
||||||
fname = QString();
|
file = FileLocation();
|
||||||
data = QByteArray();
|
data = QByteArray();
|
||||||
position = duration = 0;
|
position = duration = 0;
|
||||||
frequency = AudioVoiceMsgFrequency;
|
frequency = AudioVoiceMsgFrequency;
|
||||||
|
@ -463,9 +463,9 @@ void AudioPlayer::play(const AudioMsgId &audio, int64 position) {
|
||||||
current = &_audioData[_audioCurrent];
|
current = &_audioData[_audioCurrent];
|
||||||
}
|
}
|
||||||
current->audio = audio;
|
current->audio = audio;
|
||||||
current->fname = audio.audio->already(true);
|
current->file = audio.audio->location(true);
|
||||||
current->data = audio.audio->data;
|
current->data = audio.audio->data;
|
||||||
if (current->fname.isEmpty() && current->data.isEmpty()) {
|
if (current->file.isEmpty() && current->data.isEmpty()) {
|
||||||
setStoppedState(current, AudioPlayerStoppedAtError);
|
setStoppedState(current, AudioPlayerStoppedAtError);
|
||||||
onError(audio);
|
onError(audio);
|
||||||
} else {
|
} else {
|
||||||
|
@ -507,9 +507,9 @@ void AudioPlayer::play(const SongMsgId &song, int64 position) {
|
||||||
current = &_songData[_songCurrent];
|
current = &_songData[_songCurrent];
|
||||||
}
|
}
|
||||||
current->song = song;
|
current->song = song;
|
||||||
current->fname = song.song->already(true);
|
current->file = song.song->location(true);
|
||||||
current->data = song.song->data;
|
current->data = song.song->data;
|
||||||
if (current->fname.isEmpty() && current->data.isEmpty()) {
|
if (current->file.isEmpty() && current->data.isEmpty()) {
|
||||||
setStoppedState(current);
|
setStoppedState(current);
|
||||||
if (!song.song->loader) {
|
if (!song.song->loader) {
|
||||||
DocumentOpenLink::doOpen(song.song);
|
DocumentOpenLink::doOpen(song.song);
|
||||||
|
@ -1076,13 +1076,17 @@ void AudioPlayerFader::resumeDevice() {
|
||||||
|
|
||||||
class AudioPlayerLoader {
|
class AudioPlayerLoader {
|
||||||
public:
|
public:
|
||||||
AudioPlayerLoader(const QString &fname, const QByteArray &data) : fname(fname), data(data), dataPos(0) {
|
AudioPlayerLoader(const FileLocation &file, const QByteArray &data) : file(file), access(false), data(data), dataPos(0) {
|
||||||
}
|
}
|
||||||
virtual ~AudioPlayerLoader() {
|
virtual ~AudioPlayerLoader() {
|
||||||
|
if (access) {
|
||||||
|
file.accessDisable();
|
||||||
|
access = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check(const QString &fname, const QByteArray &data) {
|
bool check(const FileLocation &file, const QByteArray &data) {
|
||||||
return this->fname == fname && this->data.size() == data.size();
|
return this->file == file && this->data.size() == data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool open(qint64 position = 0) = 0;
|
virtual bool open(qint64 position = 0) = 0;
|
||||||
|
@ -1093,7 +1097,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QString fname;
|
FileLocation file;
|
||||||
|
bool access;
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
|
||||||
QFile f;
|
QFile f;
|
||||||
|
@ -1102,9 +1107,16 @@ protected:
|
||||||
bool openFile() {
|
bool openFile() {
|
||||||
if (data.isEmpty()) {
|
if (data.isEmpty()) {
|
||||||
if (f.isOpen()) f.close();
|
if (f.isOpen()) f.close();
|
||||||
f.setFileName(fname);
|
if (!access) {
|
||||||
|
if (!file.accessEnable()) {
|
||||||
|
LOG(("Audio Error: could not open file access '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(f.error()).arg(f.errorString()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
access = true;
|
||||||
|
}
|
||||||
|
f.setFileName(file.name());
|
||||||
if (!f.open(QIODevice::ReadOnly)) {
|
if (!f.open(QIODevice::ReadOnly)) {
|
||||||
LOG(("Audio Error: could not open file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(f.error()).arg(f.errorString()));
|
LOG(("Audio Error: could not open file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(f.error()).arg(f.errorString()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1133,7 @@ static const int32 _toChannels = 2;
|
||||||
class FFMpegLoader : public AudioPlayerLoader {
|
class FFMpegLoader : public AudioPlayerLoader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FFMpegLoader(const QString &fname, const QByteArray &data) : AudioPlayerLoader(fname, data),
|
FFMpegLoader(const FileLocation &file, const QByteArray &data) : AudioPlayerLoader(file, data),
|
||||||
freq(AudioVoiceMsgFrequency), fmt(AL_FORMAT_STEREO16),
|
freq(AudioVoiceMsgFrequency), fmt(AL_FORMAT_STEREO16),
|
||||||
sampleSize(2 * sizeof(short)), srcRate(AudioVoiceMsgFrequency), dstRate(AudioVoiceMsgFrequency),
|
sampleSize(2 * sizeof(short)), srcRate(AudioVoiceMsgFrequency), dstRate(AudioVoiceMsgFrequency),
|
||||||
maxResampleSamples(1024), dstSamplesData(0), len(0),
|
maxResampleSamples(1024), dstSamplesData(0), len(0),
|
||||||
|
@ -1143,7 +1155,7 @@ public:
|
||||||
}
|
}
|
||||||
fmtContext = avformat_alloc_context();
|
fmtContext = avformat_alloc_context();
|
||||||
if (!fmtContext) {
|
if (!fmtContext) {
|
||||||
LOG(("Audio Error: Unable to avformat_alloc_context for file '%1', data size '%2'").arg(fname).arg(data.size()));
|
LOG(("Audio Error: Unable to avformat_alloc_context for file '%1', data size '%2'").arg(file.name()).arg(data.size()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fmtContext->pb = ioContext;
|
fmtContext->pb = ioContext;
|
||||||
|
@ -1153,19 +1165,19 @@ public:
|
||||||
if ((res = avformat_open_input(&fmtContext, 0, 0, 0)) < 0) {
|
if ((res = avformat_open_input(&fmtContext, 0, 0, 0)) < 0) {
|
||||||
ioBuffer = 0;
|
ioBuffer = 0;
|
||||||
|
|
||||||
LOG(("Audio Error: Unable to avformat_open_input for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to avformat_open_input for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_opened = true;
|
_opened = true;
|
||||||
|
|
||||||
if ((res = avformat_find_stream_info(fmtContext, 0)) < 0) {
|
if ((res = avformat_find_stream_info(fmtContext, 0)) < 0) {
|
||||||
LOG(("Audio Error: Unable to avformat_find_stream_info for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to avformat_find_stream_info for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
streamId = av_find_best_stream(fmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
|
streamId = av_find_best_stream(fmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
|
||||||
if (streamId < 0) {
|
if (streamId < 0) {
|
||||||
LOG(("Audio Error: Unable to av_find_best_stream for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(streamId).arg(av_make_error_string(err, sizeof(err), streamId)));
|
LOG(("Audio Error: Unable to av_find_best_stream for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(streamId).arg(av_make_error_string(err, sizeof(err), streamId)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,7 +1185,7 @@ public:
|
||||||
codecContext = fmtContext->streams[streamId]->codec;
|
codecContext = fmtContext->streams[streamId]->codec;
|
||||||
av_opt_set_int(codecContext, "refcounted_frames", 1, 0);
|
av_opt_set_int(codecContext, "refcounted_frames", 1, 0);
|
||||||
if ((res = avcodec_open2(codecContext, codec, 0)) < 0) {
|
if ((res = avcodec_open2(codecContext, codec, 0)) < 0) {
|
||||||
LOG(("Audio Error: Unable to avcodec_open2 for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to avcodec_open2 for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1217,7 +1229,7 @@ public:
|
||||||
if (sampleSize < 0) {
|
if (sampleSize < 0) {
|
||||||
swrContext = swr_alloc();
|
swrContext = swr_alloc();
|
||||||
if (!swrContext) {
|
if (!swrContext) {
|
||||||
LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(fname).arg(data.size()));
|
LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(file.name()).arg(data.size()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int64_t src_ch_layout = layout, dst_ch_layout = _toChannelLayout;
|
int64_t src_ch_layout = layout, dst_ch_layout = _toChannelLayout;
|
||||||
|
@ -1233,7 +1245,7 @@ public:
|
||||||
av_opt_set_sample_fmt(swrContext, "out_sample_fmt", dst_sample_fmt, 0);
|
av_opt_set_sample_fmt(swrContext, "out_sample_fmt", dst_sample_fmt, 0);
|
||||||
|
|
||||||
if ((res = swr_init(swrContext)) < 0) {
|
if ((res = swr_init(swrContext)) < 0) {
|
||||||
LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,7 +1256,7 @@ public:
|
||||||
|
|
||||||
maxResampleSamples = av_rescale_rnd(AVBlockSize / sampleSize, dstRate, srcRate, AV_ROUND_UP);
|
maxResampleSamples = av_rescale_rnd(AVBlockSize / sampleSize, dstRate, srcRate, AV_ROUND_UP);
|
||||||
if ((res = av_samples_alloc_array_and_samples(&dstSamplesData, 0, _toChannels, maxResampleSamples, _toFormat, 0)) < 0) {
|
if ((res = av_samples_alloc_array_and_samples(&dstSamplesData, 0, _toChannels, maxResampleSamples, _toFormat, 0)) < 0) {
|
||||||
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1279,7 +1291,7 @@ public:
|
||||||
if ((res = av_read_frame(fmtContext, &avpkt)) < 0) {
|
if ((res = av_read_frame(fmtContext, &avpkt)) < 0) {
|
||||||
if (res != AVERROR_EOF) {
|
if (res != AVERROR_EOF) {
|
||||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||||
LOG(("Audio Error: Unable to av_read_frame() file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to av_read_frame() file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1288,7 +1300,7 @@ public:
|
||||||
int got_frame = 0;
|
int got_frame = 0;
|
||||||
if ((res = avcodec_decode_audio4(codecContext, frame, &got_frame, &avpkt)) < 0) {
|
if ((res = avcodec_decode_audio4(codecContext, frame, &got_frame, &avpkt)) < 0) {
|
||||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||||
LOG(("Audio Error: Unable to avcodec_decode_audio4() file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to avcodec_decode_audio4() file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
|
|
||||||
av_free_packet(&avpkt);
|
av_free_packet(&avpkt);
|
||||||
if (res == AVERROR_INVALIDDATA) return 0; // try to skip bad packet
|
if (res == AVERROR_INVALIDDATA) return 0; // try to skip bad packet
|
||||||
|
@ -1305,7 +1317,7 @@ public:
|
||||||
if ((res = av_samples_alloc(dstSamplesData, 0, _toChannels, maxResampleSamples, _toFormat, 1)) < 0) {
|
if ((res = av_samples_alloc(dstSamplesData, 0, _toChannels, maxResampleSamples, _toFormat, 1)) < 0) {
|
||||||
dstSamplesData[0] = 0;
|
dstSamplesData[0] = 0;
|
||||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||||
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
|
|
||||||
av_free_packet(&avpkt);
|
av_free_packet(&avpkt);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1313,7 +1325,7 @@ public:
|
||||||
}
|
}
|
||||||
if ((res = swr_convert(swrContext, dstSamplesData, dstSamples, (const uint8_t**)frame->extended_data, frame->nb_samples)) < 0) {
|
if ((res = swr_convert(swrContext, dstSamplesData, dstSamples, (const uint8_t**)frame->extended_data, frame->nb_samples)) < 0) {
|
||||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||||
LOG(("Audio Error: Unable to swr_convert for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Audio Error: Unable to swr_convert for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
|
|
||||||
av_free_packet(&avpkt);
|
av_free_packet(&avpkt);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1678,7 +1690,7 @@ AudioPlayerLoader *AudioPlayerLoaders::setupLoader(MediaOverviewType type, const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*l && (!isGoodId || !(*l)->check(m->fname, m->data))) {
|
if (*l && (!isGoodId || !(*l)->check(m->file, m->data))) {
|
||||||
delete *l;
|
delete *l;
|
||||||
*l = 0;
|
*l = 0;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -1693,23 +1705,23 @@ AudioPlayerLoader *AudioPlayerLoaders::setupLoader(MediaOverviewType type, const
|
||||||
case OverviewDocuments: _song = *static_cast<const SongMsgId*>(objId); break;
|
case OverviewDocuments: _song = *static_cast<const SongMsgId*>(objId); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray header = m->data.mid(0, 8);
|
// QByteArray header = m->data.mid(0, 8);
|
||||||
if (header.isEmpty()) {
|
// if (header.isEmpty()) {
|
||||||
QFile f(m->fname);
|
// QFile f(m->fname);
|
||||||
if (!f.open(QIODevice::ReadOnly)) {
|
// if (!f.open(QIODevice::ReadOnly)) {
|
||||||
LOG(("Audio Error: could not open file '%1'").arg(m->fname));
|
// LOG(("Audio Error: could not open file '%1'").arg(m->fname));
|
||||||
m->state = AudioPlayerStoppedAtStart;
|
// m->state = AudioPlayerStoppedAtStart;
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
header = f.read(8);
|
// header = f.read(8);
|
||||||
}
|
// }
|
||||||
if (header.size() < 8) {
|
// if (header.size() < 8) {
|
||||||
LOG(("Audio Error: could not read header from file '%1', data size %2").arg(m->fname).arg(m->data.isEmpty() ? QFileInfo(m->fname).size() : m->data.size()));
|
// LOG(("Audio Error: could not read header from file '%1', data size %2").arg(m->fname).arg(m->data.isEmpty() ? QFileInfo(m->fname).size() : m->data.size()));
|
||||||
m->state = AudioPlayerStoppedAtStart;
|
// m->state = AudioPlayerStoppedAtStart;
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
*l = new FFMpegLoader(m->fname, m->data);
|
*l = new FFMpegLoader(m->file, m->data);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
if (!(*l)->open(position)) {
|
if (!(*l)->open(position)) {
|
||||||
|
@ -1758,7 +1770,7 @@ AudioPlayer::Msg *AudioPlayerLoaders::checkLoader(MediaOverviewType type) {
|
||||||
}
|
}
|
||||||
if (!l || !m) return 0;
|
if (!l || !m) return 0;
|
||||||
|
|
||||||
if (!isGoodId || !m->loading || !(*l)->check(m->fname, m->data)) {
|
if (!isGoodId || !m->loading || !(*l)->check(m->file, m->data)) {
|
||||||
LOG(("Audio Error: playing changed while loading"));
|
LOG(("Audio Error: playing changed while loading"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2278,7 +2290,7 @@ void AudioCaptureInner::writeFrame(int32 offset, int32 framesize) {
|
||||||
class FFMpegAttributesReader : public AudioPlayerLoader {
|
class FFMpegAttributesReader : public AudioPlayerLoader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FFMpegAttributesReader(const QString &fname, const QByteArray &data) : AudioPlayerLoader(fname, data),
|
FFMpegAttributesReader(const FileLocation &file, const QByteArray &data) : AudioPlayerLoader(file, data),
|
||||||
ioBuffer(0), ioContext(0), fmtContext(0), codec(0), streamId(0),
|
ioBuffer(0), ioContext(0), fmtContext(0), codec(0), streamId(0),
|
||||||
_opened(false) {
|
_opened(false) {
|
||||||
}
|
}
|
||||||
|
@ -2488,7 +2500,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat) {
|
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat) {
|
||||||
FFMpegAttributesReader reader(fname, data);
|
FFMpegAttributesReader reader(FileLocation(StorageFilePartial, fname), data);
|
||||||
if (reader.open()) {
|
if (reader.open()) {
|
||||||
int32 duration = reader.duration() / reader.frequency();
|
int32 duration = reader.duration() / reader.frequency();
|
||||||
if (reader.duration() > 0) {
|
if (reader.duration() > 0) {
|
||||||
|
|
|
@ -127,7 +127,7 @@ private:
|
||||||
|
|
||||||
void clearData();
|
void clearData();
|
||||||
|
|
||||||
QString fname;
|
FileLocation file;
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
int64 position, duration;
|
int64 position, duration;
|
||||||
int32 frequency;
|
int32 frequency;
|
||||||
|
|
|
@ -269,7 +269,7 @@ void UpdateDownloader::unpackUpdate() {
|
||||||
}
|
}
|
||||||
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
|
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
|
||||||
RSA_free(pbKey);
|
RSA_free(pbKey);
|
||||||
if (cDevVersion()) { // try other public key, if we are in dev version
|
if (cDevVersion() || cBetaVersion()) { // try other public key, if we are in dev or beta version
|
||||||
pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(DevVersion ? UpdatesPublicKey : UpdatesPublicDevKey), -1), 0, 0, 0);
|
pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(DevVersion ? UpdatesPublicKey : UpdatesPublicDevKey), -1), 0, 0, 0);
|
||||||
if (!pbKey) {
|
if (!pbKey) {
|
||||||
LOG(("Update Error: cant read public rsa key!"));
|
LOG(("Update Error: cant read public rsa key!"));
|
||||||
|
@ -360,7 +360,19 @@ void UpdateDownloader::unpackUpdate() {
|
||||||
LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
|
LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
|
||||||
return fatalFail();
|
return fatalFail();
|
||||||
}
|
}
|
||||||
if (int32(version) <= AppVersion) {
|
|
||||||
|
quint64 betaVersion = 0;
|
||||||
|
if (version == 0x7FFFFFFF) { // beta version
|
||||||
|
stream >> betaVersion;
|
||||||
|
if (stream.status() != QDataStream::Ok) {
|
||||||
|
LOG(("Update Error: cant read beta version from downloaded stream, status: %1").arg(stream.status()));
|
||||||
|
return fatalFail();
|
||||||
|
}
|
||||||
|
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
||||||
|
LOG(("Update Error: downloaded beta version %1 is not greater, than mine %2").arg(betaVersion).arg(cBetaVersion()));
|
||||||
|
return fatalFail();
|
||||||
|
}
|
||||||
|
} else if (int32(version) <= AppVersion) {
|
||||||
LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
|
LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
|
||||||
return fatalFail();
|
return fatalFail();
|
||||||
}
|
}
|
||||||
|
@ -430,8 +442,12 @@ void UpdateDownloader::unpackUpdate() {
|
||||||
return fatalFail();
|
return fatalFail();
|
||||||
}
|
}
|
||||||
fVersion.write((const char*)&versionNum, sizeof(VerInt));
|
fVersion.write((const char*)&versionNum, sizeof(VerInt));
|
||||||
|
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||||
|
fVersion.write((const char*)&betaVersion, sizeof(quint64));
|
||||||
|
} else {
|
||||||
fVersion.write((const char*)&versionLen, sizeof(VerInt));
|
fVersion.write((const char*)&versionLen, sizeof(VerInt));
|
||||||
fVersion.write((const char*)&versionStr[0], versionLen);
|
fVersion.write((const char*)&versionStr[0], versionLen);
|
||||||
|
}
|
||||||
fVersion.close();
|
fVersion.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,12 +497,24 @@ bool checkReadyUpdate() {
|
||||||
UpdateDownloader::clearAll();
|
UpdateDownloader::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fVersion.close();
|
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||||
if (versionNum <= AppVersion) {
|
quint64 betaVersion = 0;
|
||||||
|
if (fVersion.read((char*)&betaVersion, sizeof(quint64)) != sizeof(quint64)) {
|
||||||
|
LOG(("Update Error: cant read beta version from file '%1'").arg(versionPath));
|
||||||
|
UpdateDownloader::clearAll();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
||||||
|
LOG(("Update Error: cant install beta version %1 having beta version %2").arg(betaVersion).arg(cBetaVersion()));
|
||||||
|
UpdateDownloader::clearAll();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (versionNum <= AppVersion) {
|
||||||
LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
|
LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
|
||||||
UpdateDownloader::clearAll();
|
UpdateDownloader::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
fVersion.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@ -542,3 +570,47 @@ bool checkReadyUpdate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString countBetaVersionSignature(uint64 version) { // duplicated in packer.cpp
|
||||||
|
if (cBetaPrivateKey().isEmpty()) {
|
||||||
|
LOG(("Error: Trying to count beta version signature without beta private key!"));
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray signedData = (qstr("TelegramBeta_") + QString::number(version, 16).toLower()).toUtf8();
|
||||||
|
|
||||||
|
static const int32 shaSize = 20, keySize = 128;
|
||||||
|
|
||||||
|
uchar sha1Buffer[shaSize];
|
||||||
|
hashSha1(signedData.constData(), signedData.size(), sha1Buffer); // count sha1
|
||||||
|
|
||||||
|
uint32 siglen = 0;
|
||||||
|
|
||||||
|
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(cBetaPrivateKey().constData()), -1), 0, 0, 0);
|
||||||
|
if (!prKey) {
|
||||||
|
LOG(("Error: Could not read beta private key!"));
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
if (RSA_size(prKey) != keySize) {
|
||||||
|
LOG(("Error: Bad beta private key size: %1").arg(RSA_size(prKey)));
|
||||||
|
RSA_free(prKey);
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
QByteArray signature;
|
||||||
|
signature.resize(keySize);
|
||||||
|
if (RSA_sign(NID_sha1, (const uchar*)(sha1Buffer), shaSize, (uchar*)(signature.data()), &siglen, prKey) != 1) { // count signature
|
||||||
|
LOG(("Error: Counting beta version signature failed!"));
|
||||||
|
RSA_free(prKey);
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
RSA_free(prKey);
|
||||||
|
|
||||||
|
if (siglen != keySize) {
|
||||||
|
LOG(("Error: Bad beta version signature length: %1").arg(siglen));
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
signature = signature.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
signature = signature.replace('-', '8').replace('_', 'B');
|
||||||
|
return QString::fromUtf8(signature.mid(19, 32));
|
||||||
|
}
|
||||||
|
|
|
@ -67,3 +67,5 @@ private:
|
||||||
bool checkReadyUpdate();
|
bool checkReadyUpdate();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString countBetaVersionSignature(uint64 version);
|
||||||
|
|
|
@ -25,8 +25,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
#include "autoupdater.h"
|
||||||
|
#include "boxes/confirmbox.h"
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
AboutBox::AboutBox() : AbstractBox(st::aboutWidth)
|
AboutBox::AboutBox() : AbstractBox(st::aboutWidth)
|
||||||
, _version(this, lng_about_version(lt_version, QString::fromWCharArray(AppVersionStr) + (cDevVersion() ? " dev" : "")), st::aboutVersionLink)
|
, _version(this, lng_about_version(lt_version, QString::fromWCharArray(AppVersionStr) + (cDevVersion() ? " dev" : "") + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())), st::aboutVersionLink)
|
||||||
, _text1(this, lang(lng_about_text_1), st::aboutLabel, st::aboutTextStyle)
|
, _text1(this, lang(lng_about_text_1), st::aboutLabel, st::aboutTextStyle)
|
||||||
, _text2(this, lang(lng_about_text_2), st::aboutLabel, st::aboutTextStyle)
|
, _text2(this, lang(lng_about_text_2), st::aboutLabel, st::aboutTextStyle)
|
||||||
, _text3(this, QString(), st::aboutLabel, st::aboutTextStyle)
|
, _text3(this, QString(), st::aboutLabel, st::aboutTextStyle)
|
||||||
|
@ -66,7 +71,23 @@ void AboutBox::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutBox::onVersion() {
|
void AboutBox::onVersion() {
|
||||||
|
if (cRealBetaVersion()) {
|
||||||
|
QString url = qsl("https://tdesktop.com/");
|
||||||
|
switch (cPlatform()) {
|
||||||
|
case dbipWindows: url += qsl("win/%1.zip"); break;
|
||||||
|
case dbipMac: url += qsl("mac/%1.zip"); break;
|
||||||
|
case dbipMacOld: url += qsl("mac32/%1.zip"); break;
|
||||||
|
case dbipLinux32: url += qsl("linux32/%1.tar.xz"); break;
|
||||||
|
case dbipLinux64: url += qsl("linux/%1.tar.xz"); break;
|
||||||
|
}
|
||||||
|
url = url.arg(qsl("tbeta%1_%2").arg(cRealBetaVersion()).arg(countBetaVersionSignature(cRealBetaVersion())));
|
||||||
|
|
||||||
|
App::app()->clipboard()->setText(url);
|
||||||
|
|
||||||
|
App::showLayer(new InformBox("The link to the current private beta version of Telegram Desktop was copied to the clipboard."));
|
||||||
|
} else {
|
||||||
QDesktopServices::openUrl(qsl("https://desktop.telegram.org/?_hash=changelog"));
|
QDesktopServices::openUrl(qsl("https://desktop.telegram.org/?_hash=changelog"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutBox::keyPressEvent(QKeyEvent *e) {
|
void AboutBox::keyPressEvent(QKeyEvent *e) {
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace {
|
||||||
|
|
||||||
ContactsInner::ContactsInner(ChatData *chat, MembersFilter membersFilter) : TWidget()
|
ContactsInner::ContactsInner(ChatData *chat, MembersFilter membersFilter) : TWidget()
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
, _newItemHeight((membersFilter == MembersFilterAdmins) ? (st::contactsNewItemHeight + st::contactsAboutHeight) : 0)
|
, _newItemHeight(0)
|
||||||
, _newItemSel(false)
|
, _newItemSel(false)
|
||||||
, _chat(chat)
|
, _chat(chat)
|
||||||
, _channel(0)
|
, _channel(0)
|
||||||
|
@ -119,9 +119,12 @@ ContactsInner::ContactsInner(ChatData *chat, MembersFilter membersFilter) : TWid
|
||||||
, _addContactLnk(this, lang(lng_add_contact_button))
|
, _addContactLnk(this, lang(lng_add_contact_button))
|
||||||
, _saving(false) {
|
, _saving(false) {
|
||||||
initList();
|
initList();
|
||||||
if (membersFilter == MembersFilterAdmins && !_contacts->list.count) {
|
if (membersFilter == MembersFilterAdmins) {
|
||||||
|
_newItemHeight = st::contactsNewItemHeight + qMax(_aboutAllAdmins.countHeight(_aboutWidth), _aboutAdmins.countHeight(_aboutWidth)) + st::contactsAboutHeight;
|
||||||
|
if (!_contacts->list.count) {
|
||||||
App::api()->requestFullPeer(_chat);
|
App::api()->requestFullPeer(_chat);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,9 +778,9 @@ void ContactsInner::changeCheckState(ContactData *data, PeerData *peer) {
|
||||||
int32 ContactsInner::selectedCount() const {
|
int32 ContactsInner::selectedCount() const {
|
||||||
int32 result = _selCount;
|
int32 result = _selCount;
|
||||||
if (_chat) {
|
if (_chat) {
|
||||||
result += (_chat->count > 0) ? _chat->count : 1;
|
result += qMax(_chat->count, 1);
|
||||||
} else if (_channel) {
|
} else if (_channel) {
|
||||||
result += _already.size();
|
result += qMax(_channel->count, _already.size());
|
||||||
} else if (_creating == CreatingGroupGroup) {
|
} else if (_creating == CreatingGroupGroup) {
|
||||||
result += 1;
|
result += 1;
|
||||||
}
|
}
|
||||||
|
@ -1379,6 +1382,7 @@ void ContactsBox::init() {
|
||||||
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSel()));
|
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSel()));
|
||||||
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
|
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
|
||||||
connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
|
connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
|
||||||
|
connect(&_filter, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
|
||||||
connect(&_filterCancel, SIGNAL(clicked()), this, SLOT(onFilterCancel()));
|
connect(&_filterCancel, SIGNAL(clicked()), this, SLOT(onFilterCancel()));
|
||||||
connect(&_inner, SIGNAL(mustScrollTo(int, int)), &_scroll, SLOT(scrollToY(int, int)));
|
connect(&_inner, SIGNAL(mustScrollTo(int, int)), &_scroll, SLOT(scrollToY(int, int)));
|
||||||
connect(&_inner, SIGNAL(selectAllQuery()), &_filter, SLOT(selectAll()));
|
connect(&_inner, SIGNAL(selectAllQuery()), &_filter, SLOT(selectAll()));
|
||||||
|
@ -1500,14 +1504,12 @@ void ContactsBox::showDone() {
|
||||||
_filter.setFocus();
|
_filter.setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::keyPressEvent(QKeyEvent *e) {
|
void ContactsBox::onSubmit() {
|
||||||
if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
|
|
||||||
if (_filter.hasFocus()) {
|
|
||||||
_inner.chooseParticipant();
|
_inner.chooseParticipant();
|
||||||
} else {
|
}
|
||||||
ItemListBox::keyPressEvent(e);
|
|
||||||
}
|
void ContactsBox::keyPressEvent(QKeyEvent *e) {
|
||||||
} else if (_filter.hasFocus()) {
|
if (_filter.hasFocus()) {
|
||||||
if (e->key() == Qt::Key_Down) {
|
if (e->key() == Qt::Key_Down) {
|
||||||
_inner.selectSkip(1);
|
_inner.selectSkip(1);
|
||||||
} else if (e->key() == Qt::Key_Up) {
|
} else if (e->key() == Qt::Key_Up) {
|
||||||
|
@ -1770,7 +1772,10 @@ MembersInner::MembersInner(ChannelData *channel, MembersFilter filter) : TWidget
|
||||||
, _kickRequestId(0)
|
, _kickRequestId(0)
|
||||||
, _kickBox(0)
|
, _kickBox(0)
|
||||||
, _loading(true)
|
, _loading(true)
|
||||||
, _loadingRequestId(0) {
|
, _loadingRequestId(0)
|
||||||
|
, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right())
|
||||||
|
, _about(_aboutWidth)
|
||||||
|
, _aboutHeight(0) {
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
connect(App::main(), SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
|
connect(App::main(), SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
|
||||||
connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
||||||
|
@ -1821,6 +1826,10 @@ void MembersInner::paintEvent(QPaintEvent *e) {
|
||||||
paintDialog(p, _rows[from], data(from), sel, kickSel, kickDown);
|
paintDialog(p, _rows[from], data(from), sel, kickSel, kickDown);
|
||||||
p.translate(0, _rowHeight);
|
p.translate(0, _rowHeight);
|
||||||
}
|
}
|
||||||
|
if (to == _rows.size() && _filter == MembersFilterRecent && (_rows.size() < _channel->count || _rows.size() >= cMaxGroupCount())) {
|
||||||
|
p.setPen(st::stickersReorderFg);
|
||||||
|
_about.draw(p, st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, style::al_center);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1909,7 +1918,7 @@ void MembersInner::paintDialog(Painter &p, PeerData *peer, MemberData *data, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setFont(st::contactsStatusFont->f);
|
p.setFont(st::contactsStatusFont->f);
|
||||||
p.setPen(sel ? st::contactsStatusFgOver : (data->onlineColor ? st::contactsStatusFgOnline : st::contactsStatusFg));
|
p.setPen(data->onlineColor ? st::contactsStatusFgOnline : (sel ? st::contactsStatusFgOver : st::contactsStatusFg));
|
||||||
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), data->online);
|
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), data->online);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1992,8 +2001,14 @@ void MembersInner::chooseParticipant() {
|
||||||
void MembersInner::refresh() {
|
void MembersInner::refresh() {
|
||||||
if (_rows.isEmpty()) {
|
if (_rows.isEmpty()) {
|
||||||
resize(width(), st::membersPadding.top() + st::noContactsHeight + st::membersPadding.bottom());
|
resize(width(), st::membersPadding.top() + st::noContactsHeight + st::membersPadding.bottom());
|
||||||
|
_aboutHeight = 0;
|
||||||
} else {
|
} else {
|
||||||
resize(width(), st::membersPadding.top() + _newItemHeight + _rows.size() * _rowHeight + st::membersPadding.bottom());
|
_about.setText(st::boxTextFont, lng_channel_only_last_shown(lt_count, _rows.size()));
|
||||||
|
_aboutHeight = st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom();
|
||||||
|
if (_filter != MembersFilterRecent || (_rows.size() >= _channel->count && _rows.size() < cMaxGroupCount())) {
|
||||||
|
_aboutHeight = 0;
|
||||||
|
}
|
||||||
|
resize(width(), st::membersPadding.top() + _newItemHeight + _rows.size() * _rowHeight + st::membersPadding.bottom() + _aboutHeight);
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -2228,6 +2243,7 @@ void MembersInner::removeKicked() {
|
||||||
--_channel->adminsCount;
|
--_channel->adminsCount;
|
||||||
if (App::main()) emit App::main()->peerUpdated(_channel);
|
if (App::main()) emit App::main()->peerUpdated(_channel);
|
||||||
}
|
}
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
_kickConfirm = 0;
|
_kickConfirm = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,6 +216,8 @@ public slots:
|
||||||
void onCreate();
|
void onCreate();
|
||||||
void onSaveAdmins();
|
void onSaveAdmins();
|
||||||
|
|
||||||
|
void onSubmit();
|
||||||
|
|
||||||
bool onSearchByUsername(bool searchCache = false);
|
bool onSearchByUsername(bool searchCache = false);
|
||||||
void onNeedSearchByUsername();
|
void onNeedSearchByUsername();
|
||||||
|
|
||||||
|
@ -386,6 +388,10 @@ private:
|
||||||
MemberRoles _roles;
|
MemberRoles _roles;
|
||||||
MemberDatas _datas;
|
MemberDatas _datas;
|
||||||
|
|
||||||
|
int32 _aboutWidth;
|
||||||
|
Text _about;
|
||||||
|
int32 _aboutHeight;
|
||||||
|
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,15 +25,17 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "downloadpathbox.h"
|
#include "downloadpathbox.h"
|
||||||
#include "gui/filedialog.h"
|
#include "gui/filedialog.h"
|
||||||
|
#include "pspecific.h"
|
||||||
|
|
||||||
DownloadPathBox::DownloadPathBox() :
|
DownloadPathBox::DownloadPathBox() : AbstractBox()
|
||||||
_path(cDownloadPath()),
|
, _path(cDownloadPath())
|
||||||
_default(this, qsl("dir_type"), 0, lang(lng_download_path_default_radio), _path.isEmpty()),
|
, _pathBookmark(cDownloadPathBookmark())
|
||||||
_temp(this, qsl("dir_type"), 1, lang(lng_download_path_temp_radio), _path == qsl("tmp")),
|
, _default(this, qsl("dir_type"), 0, lang(lng_download_path_default_radio), _path.isEmpty())
|
||||||
_dir(this, qsl("dir_type"), 2, lang(lng_download_path_dir_radio), !_path.isEmpty() && _path != qsl("tmp")),
|
, _temp(this, qsl("dir_type"), 1, lang(lng_download_path_temp_radio), _path == qsl("tmp"))
|
||||||
_pathLink(this, QString(), st::defaultBoxLinkButton),
|
, _dir(this, qsl("dir_type"), 2, lang(lng_download_path_dir_radio), !_path.isEmpty() && _path != qsl("tmp"))
|
||||||
_save(this, lang(lng_connection_save), st::defaultBoxButton),
|
, _pathLink(this, QString(), st::defaultBoxLinkButton)
|
||||||
_cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
, _save(this, lang(lng_connection_save), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||||
|
|
||||||
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
@ -124,12 +126,13 @@ void DownloadPathBox::onChange() {
|
||||||
void DownloadPathBox::onEditPath() {
|
void DownloadPathBox::onEditPath() {
|
||||||
filedialogInit();
|
filedialogInit();
|
||||||
QString path, lastPath = cDialogLastPath();
|
QString path, lastPath = cDialogLastPath();
|
||||||
if (!cDownloadPath().isEmpty()) {
|
if (!cDownloadPath().isEmpty() && cDownloadPath() != qstr("tmp")) {
|
||||||
cSetDialogLastPath(cDownloadPath());
|
cSetDialogLastPath(cDownloadPath().left(cDownloadPath().size() - (cDownloadPath().endsWith('/') ? 1 : 0)));
|
||||||
}
|
}
|
||||||
if (filedialogGetDir(path, lang(lng_download_path_choose))) {
|
if (filedialogGetDir(path, lang(lng_download_path_choose))) {
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
_path = path + '/';
|
_path = path + '/';
|
||||||
|
_pathBookmark = psDownloadPathBookmark(_path);
|
||||||
setPathText(QDir::toNativeSeparators(_path));
|
setPathText(QDir::toNativeSeparators(_path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,6 +141,7 @@ void DownloadPathBox::onEditPath() {
|
||||||
|
|
||||||
void DownloadPathBox::onSave() {
|
void DownloadPathBox::onSave() {
|
||||||
cSetDownloadPath(_default.checked() ? QString() : (_temp.checked() ? qsl("tmp") : _path));
|
cSetDownloadPath(_default.checked() ? QString() : (_temp.checked() ? qsl("tmp") : _path));
|
||||||
|
cSetDownloadPathBookmark((_default.checked() || _temp.checked()) ? QByteArray() : _pathBookmark);
|
||||||
Local::writeUserSettings();
|
Local::writeUserSettings();
|
||||||
emit closed();
|
emit closed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ private:
|
||||||
void setPathText(const QString &text);
|
void setPathText(const QString &text);
|
||||||
|
|
||||||
QString _path;
|
QString _path;
|
||||||
|
QByteArray _pathBookmark;
|
||||||
|
|
||||||
Radiobutton _default, _temp, _dir;
|
Radiobutton _default, _temp, _dir;
|
||||||
LinkButton _pathLink;
|
LinkButton _pathLink;
|
||||||
|
|
|
@ -125,7 +125,11 @@ PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QSt
|
||||||
, _compressed(this, lang(lng_send_image_compressed), true)
|
, _compressed(this, lang(lng_send_image_compressed), true)
|
||||||
, _send(this, lang(lng_send_button), st::defaultBoxButton)
|
, _send(this, lang(lng_send_button), st::defaultBoxButton)
|
||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||||
, _phone(phone), _fname(fname), _lname(lname), _replyTo(replyTo) {
|
, _phone(phone)
|
||||||
|
, _fname(fname)
|
||||||
|
, _lname(lname)
|
||||||
|
, _replyTo(replyTo)
|
||||||
|
, _confirmed(false) {
|
||||||
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
|
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ _input(set), _installRequest(0) {
|
||||||
case mtpc_inputStickerSetShortName: _setShortName = qs(set.c_inputStickerSetShortName().vshort_name); break;
|
case mtpc_inputStickerSetShortName: _setShortName = qs(set.c_inputStickerSetShortName().vshort_name); break;
|
||||||
}
|
}
|
||||||
MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet));
|
MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet));
|
||||||
cSetLastStickersUpdate(0);
|
|
||||||
App::main()->updateStickers();
|
App::main()->updateStickers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||||
}
|
}
|
||||||
if (d.vset.type() == mtpc_stickerSet) {
|
if (d.vset.type() == mtpc_stickerSet) {
|
||||||
const MTPDstickerSet &s(d.vset.c_stickerSet());
|
const MTPDstickerSet &s(d.vset.c_stickerSet());
|
||||||
_setTitle = qs(s.vtitle);
|
_setTitle = stickerSetTitle(s);
|
||||||
_title = st::boxTitleFont->elided(_setTitle, width() - st::boxTitlePosition.x() - st::boxTitleHeight);
|
_title = st::boxTitleFont->elided(_setTitle, width() - st::boxTitlePosition.x() - st::boxTitleHeight);
|
||||||
_setShortName = qs(s.vshort_name);
|
_setShortName = qs(s.vshort_name);
|
||||||
_setId = s.vid.v;
|
_setId = s.vid.v;
|
||||||
|
@ -91,23 +90,14 @@ bool StickerSetInner::failedSet(const RPCError &error) {
|
||||||
void StickerSetInner::installDone(const MTPBool &result) {
|
void StickerSetInner::installDone(const MTPBool &result) {
|
||||||
StickerSets &sets(cRefStickerSets());
|
StickerSets &sets(cRefStickerSets());
|
||||||
|
|
||||||
|
_setFlags &= ~MTPDstickerSet::flag_disabled;
|
||||||
sets.insert(_setId, StickerSet(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)).value().stickers = _pack;
|
sets.insert(_setId, StickerSet(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)).value().stickers = _pack;
|
||||||
|
|
||||||
int32 insertAtIndex = 0;
|
|
||||||
StickerSetsOrder &order(cRefStickerSetsOrder());
|
StickerSetsOrder &order(cRefStickerSetsOrder());
|
||||||
for (int32 s = order.size(); insertAtIndex < s; ++insertAtIndex) {
|
int32 insertAtIndex = 0, currentIndex = order.indexOf(_setId);
|
||||||
StickerSets::const_iterator i = sets.constFind(order.at(insertAtIndex));
|
|
||||||
if (i == sets.cend() || !(i->flags & MTPDstickerSet::flag_official)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int32 currentIndex = cStickerSetsOrder().indexOf(_setId);
|
|
||||||
if (currentIndex != insertAtIndex) {
|
if (currentIndex != insertAtIndex) {
|
||||||
if (currentIndex > 0) {
|
if (currentIndex > 0) {
|
||||||
order.removeAt(currentIndex);
|
order.removeAt(currentIndex);
|
||||||
if (currentIndex < insertAtIndex) {
|
|
||||||
--insertAtIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
order.insert(insertAtIndex, _setId);
|
order.insert(insertAtIndex, _setId);
|
||||||
}
|
}
|
||||||
|
@ -115,13 +105,14 @@ void StickerSetInner::installDone(const MTPBool &result) {
|
||||||
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
||||||
if (custom != sets.cend()) {
|
if (custom != sets.cend()) {
|
||||||
for (int32 i = 0, l = _pack.size(); i < l; ++i) {
|
for (int32 i = 0, l = _pack.size(); i < l; ++i) {
|
||||||
custom->stickers.removeOne(_pack.at(i));
|
int32 removeIndex = custom->stickers.indexOf(_pack.at(i));
|
||||||
|
if (removeIndex >= 0) custom->stickers.removeAt(removeIndex);
|
||||||
}
|
}
|
||||||
if (custom->stickers.isEmpty()) {
|
if (custom->stickers.isEmpty()) {
|
||||||
sets.erase(custom);
|
sets.erase(custom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cSetStickersHash(QByteArray());
|
cSetStickersHash(stickersCountHash());
|
||||||
Local::writeStickers();
|
Local::writeStickers();
|
||||||
emit installed(_setId);
|
emit installed(_setId);
|
||||||
App::wnd()->hideLayer();
|
App::wnd()->hideLayer();
|
||||||
|
@ -195,7 +186,10 @@ bool StickerSetInner::loaded() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 StickerSetInner::notInstalled() const {
|
int32 StickerSetInner::notInstalled() const {
|
||||||
return (_loaded && (cStickerSets().constFind(_setId) == cStickerSets().cend())) ? _pack.size() : 0;
|
if (!_loaded) return 0;
|
||||||
|
StickerSets::const_iterator it = cStickerSets().constFind(_setId);
|
||||||
|
if (it == cStickerSets().cend() || (it->flags & MTPDstickerSet::flag_disabled)) return _pack.size();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickerSetInner::official() const {
|
bool StickerSetInner::official() const {
|
||||||
|
@ -285,16 +279,16 @@ void StickerSetBox::showAll() {
|
||||||
int32 cnt = _inner.notInstalled();
|
int32 cnt = _inner.notInstalled();
|
||||||
if (_inner.loaded()) {
|
if (_inner.loaded()) {
|
||||||
_shadow.show();
|
_shadow.show();
|
||||||
if (_inner.official()) {
|
if (_inner.notInstalled()) {
|
||||||
_add.hide();
|
|
||||||
_share.hide();
|
|
||||||
_cancel.hide();
|
|
||||||
_done.show();
|
|
||||||
} else if (_inner.notInstalled()) {
|
|
||||||
_add.show();
|
_add.show();
|
||||||
_cancel.show();
|
_cancel.show();
|
||||||
_share.hide();
|
_share.hide();
|
||||||
_done.hide();
|
_done.hide();
|
||||||
|
} else if (_inner.official()) {
|
||||||
|
_add.hide();
|
||||||
|
_share.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
_done.show();
|
||||||
} else {
|
} else {
|
||||||
_share.show();
|
_share.show();
|
||||||
_cancel.show();
|
_cancel.show();
|
||||||
|
@ -334,3 +328,625 @@ void StickerSetBox::resizeEvent(QResizeEvent *e) {
|
||||||
_cancel.moveToRight(st::boxButtonPadding.right() + _add.width() + st::boxButtonPadding.left(), _add.y());
|
_cancel.moveToRight(st::boxButtonPadding.right() + _add.width() + st::boxButtonPadding.left(), _add.y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StickersInner::StickersInner() : TWidget()
|
||||||
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
|
, _aboveShadowFadeStart(0)
|
||||||
|
, _aboveShadowFadeOpacity(0, 0)
|
||||||
|
, _a_shifting(animFunc(this, &StickersInner::animStep_shifting))
|
||||||
|
, _itemsTop(st::membersPadding.top())
|
||||||
|
, _saving(false)
|
||||||
|
, _removeSel(-1)
|
||||||
|
, _removeDown(-1)
|
||||||
|
, _removeWidth(st::normalFont->width(lang(lng_stickers_remove)))
|
||||||
|
, _returnWidth(st::normalFont->width(lang(lng_stickers_return)))
|
||||||
|
, _restoreWidth(st::normalFont->width(lang(lng_stickers_restore)))
|
||||||
|
, _selected(-1)
|
||||||
|
, _started(-1)
|
||||||
|
, _dragging(-1)
|
||||||
|
, _above(-1)
|
||||||
|
, _aboveShadow(st::boxShadow)
|
||||||
|
, _scrollbar(0) {
|
||||||
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
|
setMouseTracking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::paintEvent(QPaintEvent *e) {
|
||||||
|
QRect r(e->rect());
|
||||||
|
Painter p(this);
|
||||||
|
|
||||||
|
updateAnimatedValues();
|
||||||
|
|
||||||
|
p.fillRect(r, st::white);
|
||||||
|
p.setClipRect(r);
|
||||||
|
if (_rows.isEmpty()) {
|
||||||
|
p.setFont(st::noContactsFont->f);
|
||||||
|
p.setPen(st::noContactsColor->p);
|
||||||
|
p.drawText(QRect(0, 0, width(), st::noContactsHeight), lang(lng_contacts_loading), style::al_center);
|
||||||
|
} else {
|
||||||
|
p.translate(0, _itemsTop);
|
||||||
|
|
||||||
|
int32 yFrom = r.y() - _itemsTop, yTo = r.y() + r.height() - _itemsTop;
|
||||||
|
int32 from = floorclamp(yFrom - _rowHeight, _rowHeight, 0, _rows.size());
|
||||||
|
int32 to = ceilclamp(yTo + _rowHeight, _rowHeight, 0, _rows.size());
|
||||||
|
p.translate(0, from * _rowHeight);
|
||||||
|
for (int32 i = from; i < to; ++i) {
|
||||||
|
if (i != _above) {
|
||||||
|
paintRow(p, i);
|
||||||
|
}
|
||||||
|
p.translate(0, _rowHeight);
|
||||||
|
}
|
||||||
|
if (from <= _above && _above < to) {
|
||||||
|
p.translate(0, (_above - to) * _rowHeight);
|
||||||
|
paintRow(p, _above);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::paintRow(Painter &p, int32 index) {
|
||||||
|
const StickerSetRow *s(_rows.at(index));
|
||||||
|
|
||||||
|
int32 xadd = 0, yadd = s->yadd.current();
|
||||||
|
if (xadd || yadd) p.translate(xadd, yadd);
|
||||||
|
|
||||||
|
bool removeSel = (index == _removeSel && (_removeDown < 0 || index == _removeDown));
|
||||||
|
bool removeDown = removeSel && (index == _removeDown);
|
||||||
|
|
||||||
|
p.setFont((removeSel ? st::linkOverFont : st::linkFont)->f);
|
||||||
|
if (removeDown) {
|
||||||
|
p.setPen(st::btnDefLink.downColor->p);
|
||||||
|
} else {
|
||||||
|
p.setPen(st::btnDefLink.color->p);
|
||||||
|
}
|
||||||
|
int32 remWidth = s->disabled ? (s->official ? _restoreWidth : _returnWidth) : _removeWidth;
|
||||||
|
QString remText = lang(s->disabled ? (s->official ? lng_stickers_restore : lng_stickers_return) : lng_stickers_remove);
|
||||||
|
p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), remText, remWidth);
|
||||||
|
|
||||||
|
if (index == _above) {
|
||||||
|
float64 current = _aboveShadowFadeOpacity.current();
|
||||||
|
if (_started >= 0) {
|
||||||
|
float64 o = aboveShadowOpacity();
|
||||||
|
if (o > current) {
|
||||||
|
_aboveShadowFadeOpacity = anim::fvalue(o, o);
|
||||||
|
current = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.setOpacity(current);
|
||||||
|
QRect row(myrtlrect(_aboveShadow.getDimensions(st::boxShadowShift).left(), st::contactsPadding.top() / 2, width() - (st::contactsPadding.left() / 2) - _scrollbar - _aboveShadow.getDimensions(st::boxShadowShift).right(), _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2)));
|
||||||
|
_aboveShadow.paint(p, row, st::boxShadowShift);
|
||||||
|
p.fillRect(row, st::white);
|
||||||
|
p.setOpacity(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->disabled) p.setOpacity(st::stickersRowDisabledOpacity);
|
||||||
|
if (s->sticker) {
|
||||||
|
s->sticker->thumb->load();
|
||||||
|
QPixmap pix(s->sticker->thumb->pix(s->pixw, s->pixh));
|
||||||
|
p.drawPixmapLeft(st::contactsPadding.left() + (st::contactsPhotoSize - s->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - s->pixh) / 2, width(), pix);
|
||||||
|
}
|
||||||
|
p.setFont(st::contactsNameFont);
|
||||||
|
p.setPen(st::black);
|
||||||
|
|
||||||
|
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||||
|
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsNameTop, width(), s->title);
|
||||||
|
|
||||||
|
p.setFont(st::contactsStatusFont);
|
||||||
|
p.setPen(st::contactsStatusFg);
|
||||||
|
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), lng_stickers_count(lt_count, s->count));
|
||||||
|
|
||||||
|
p.setOpacity(1);
|
||||||
|
if (xadd || yadd) p.translate(-xadd, -yadd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::mousePressEvent(QMouseEvent *e) {
|
||||||
|
if (_saving) return;
|
||||||
|
if (_dragging >= 0) mouseReleaseEvent(e);
|
||||||
|
_mouse = e->globalPos();
|
||||||
|
onUpdateSelected();
|
||||||
|
if (_removeSel >= 0) {
|
||||||
|
_removeDown = _removeSel;
|
||||||
|
update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight);
|
||||||
|
} else if (_selected >= 0) {
|
||||||
|
_above = _dragging = _started = _selected;
|
||||||
|
_dragStart = mapFromGlobal(_mouse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
if (_saving) return;
|
||||||
|
_mouse = e->globalPos();
|
||||||
|
onUpdateSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::onUpdateSelected() {
|
||||||
|
if (_saving) return;
|
||||||
|
QPoint local(mapFromGlobal(_mouse));
|
||||||
|
if (_dragging >= 0) {
|
||||||
|
int32 shift = 0;
|
||||||
|
uint64 ms = getms();
|
||||||
|
if (_dragStart.y() > local.y() && _dragging > 0) {
|
||||||
|
shift = -floorclamp(_dragStart.y() - local.y() + (_rowHeight / 2), _rowHeight, 0, _dragging);
|
||||||
|
for (int32 from = _dragging, to = _dragging + shift; from > to; --from) {
|
||||||
|
qSwap(_rows[from], _rows[from - 1]);
|
||||||
|
_rows.at(from)->yadd = anim::ivalue(_rows.at(from)->yadd.current() - _rowHeight, 0);
|
||||||
|
_animStartTimes[from] = ms;
|
||||||
|
}
|
||||||
|
} else if (_dragStart.y() < local.y() && _dragging + 1 < _rows.size()) {
|
||||||
|
shift = floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1);
|
||||||
|
for (int32 from = _dragging, to = _dragging + shift; from < to; ++from) {
|
||||||
|
qSwap(_rows[from], _rows[from + 1]);
|
||||||
|
_rows.at(from)->yadd = anim::ivalue(_rows.at(from)->yadd.current() + _rowHeight, 0);
|
||||||
|
_animStartTimes[from] = ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shift) {
|
||||||
|
_dragging += shift;
|
||||||
|
_above = _dragging;
|
||||||
|
_dragStart.setY(_dragStart.y() + shift * _rowHeight);
|
||||||
|
if (!_a_shifting.animating()) {
|
||||||
|
_a_shifting.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_rows.at(_dragging)->yadd = anim::ivalue(local.y() - _dragStart.y(), local.y() - _dragStart.y());
|
||||||
|
_animStartTimes[_dragging] = 0;
|
||||||
|
updateAnimatedRegions();
|
||||||
|
|
||||||
|
emit checkDraggingScroll(local.y());
|
||||||
|
} else {
|
||||||
|
bool in = rect().marginsRemoved(QMargins(0, _itemsTop, 0, st::membersPadding.bottom())).contains(local);
|
||||||
|
_selected = in ? floorclamp(local.y() - _itemsTop, _rowHeight, 0, _rows.size() - 1) : -1;
|
||||||
|
int32 removeSel = -1;
|
||||||
|
|
||||||
|
if (_selected >= 0) {
|
||||||
|
int32 remw = _rows.at(_selected)->disabled ? (_rows.at(_selected)->official ? _restoreWidth : _returnWidth) : _removeWidth;
|
||||||
|
QRect rem(myrtlrect(width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - remw, st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, remw, st::normalFont->height));
|
||||||
|
removeSel = rem.contains(local.x(), local.y() - _itemsTop - _selected * _rowHeight) ? _selected : -1;
|
||||||
|
}
|
||||||
|
setRemoveSel(removeSel);
|
||||||
|
emit noDraggingScroll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float64 StickersInner::aboveShadowOpacity() const {
|
||||||
|
if (_above < 0) return 0;
|
||||||
|
|
||||||
|
int32 dx = 0;
|
||||||
|
int32 dy = qAbs(_above * _rowHeight + _rows.at(_above)->yadd.current() - _started * _rowHeight);
|
||||||
|
return qMin((dx + dy) * 2. / _rowHeight, 1.);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
if (_saving) return;
|
||||||
|
_mouse = e->globalPos();
|
||||||
|
onUpdateSelected();
|
||||||
|
if (_removeDown == _removeSel && _removeSel >= 0) {
|
||||||
|
_rows[_removeDown]->disabled = !_rows[_removeDown]->disabled;
|
||||||
|
} else if (_dragging >= 0) {
|
||||||
|
QPoint local(mapFromGlobal(_mouse));
|
||||||
|
_rows[_dragging]->yadd.start(0);
|
||||||
|
_aboveShadowFadeStart = _animStartTimes[_dragging] = getms();
|
||||||
|
_aboveShadowFadeOpacity = anim::fvalue(aboveShadowOpacity(), 0);
|
||||||
|
if (!_a_shifting.animating()) {
|
||||||
|
_a_shifting.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
_dragging = _started = -1;
|
||||||
|
}
|
||||||
|
if (_removeDown >= 0) {
|
||||||
|
update(0, _itemsTop + _removeDown * _rowHeight, width(), _rowHeight);
|
||||||
|
_removeDown = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::updateAnimatedRegions() {
|
||||||
|
int32 updateMin = -1, updateMax = 0;
|
||||||
|
for (int32 i = 0, l = _animStartTimes.size(); i < l; ++i) {
|
||||||
|
if (_animStartTimes.at(i)) {
|
||||||
|
if (updateMin < 0) updateMin = i;
|
||||||
|
updateMax = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_aboveShadowFadeStart) {
|
||||||
|
if (updateMin < 0 || updateMin > _above) updateMin = _above;
|
||||||
|
if (updateMax < _above) updateMin = _above;
|
||||||
|
}
|
||||||
|
if (_dragging >= 0) {
|
||||||
|
if (updateMin < 0 || updateMin > _dragging) updateMin = _dragging;
|
||||||
|
if (updateMax < _dragging) updateMax = _dragging;
|
||||||
|
}
|
||||||
|
if (updateMin >= 0) {
|
||||||
|
update(0, _itemsTop + _rowHeight * (updateMin - 1), width(), _rowHeight * (updateMax - updateMin + 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StickersInner::updateAnimatedValues() {
|
||||||
|
bool animating = false;
|
||||||
|
uint64 ms = getms();
|
||||||
|
for (int32 i = 0, l = _animStartTimes.size(); i < l; ++i) {
|
||||||
|
uint64 start = _animStartTimes.at(i);
|
||||||
|
if (start) {
|
||||||
|
if (start + st::stickersRowDuration > ms && ms >= start) {
|
||||||
|
_rows.at(i)->yadd.update((ms - start) / st::stickersRowDuration, anim::sineInOut);
|
||||||
|
animating = true;
|
||||||
|
} else {
|
||||||
|
_rows.at(i)->yadd.finish();
|
||||||
|
_animStartTimes[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_aboveShadowFadeStart) {
|
||||||
|
if (_aboveShadowFadeStart + st::stickersRowDuration > ms && ms > _aboveShadowFadeStart) {
|
||||||
|
_aboveShadowFadeOpacity.update((ms - _aboveShadowFadeStart) / st::stickersRowDuration, anim::sineInOut);
|
||||||
|
animating = true;
|
||||||
|
} else {
|
||||||
|
_aboveShadowFadeOpacity.finish();
|
||||||
|
_aboveShadowFadeStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return animating;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StickersInner::animStep_shifting(float64) {
|
||||||
|
updateAnimatedRegions();
|
||||||
|
|
||||||
|
bool animating = updateAnimatedValues();
|
||||||
|
if (!animating) {
|
||||||
|
_above = _dragging;
|
||||||
|
}
|
||||||
|
return animating;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::clear() {
|
||||||
|
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
|
||||||
|
delete _rows.at(i);
|
||||||
|
}
|
||||||
|
_rows.clear();
|
||||||
|
_animStartTimes.clear();
|
||||||
|
_aboveShadowFadeStart = 0;
|
||||||
|
_aboveShadowFadeOpacity = anim::fvalue(0, 0);
|
||||||
|
_a_shifting.stop();
|
||||||
|
_above = _dragging = _started = -1;
|
||||||
|
_selected = -1;
|
||||||
|
_removeDown = -1;
|
||||||
|
setRemoveSel(-1);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::setRemoveSel(int32 removeSel) {
|
||||||
|
if (removeSel != _removeSel) {
|
||||||
|
if (_removeSel >= 0) update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight);
|
||||||
|
_removeSel = removeSel;
|
||||||
|
if (_removeSel >= 0) update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight);
|
||||||
|
setCursor((_removeSel >= 0 && (_removeDown < 0 || _removeDown == _removeSel)) ? style::cur_pointer : style::cur_default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::rebuild() {
|
||||||
|
QList<StickerSetRow*> rows, rowsDisabled;
|
||||||
|
|
||||||
|
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||||
|
int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(qMax(_returnWidth, _removeWidth), _restoreWidth);
|
||||||
|
|
||||||
|
clear();
|
||||||
|
const StickerSetsOrder &order(cStickerSetsOrder());
|
||||||
|
_animStartTimes.reserve(order.size());
|
||||||
|
|
||||||
|
const StickerSets &sets(cStickerSets());
|
||||||
|
for (int32 i = 0, l = order.size(); i < l; ++i) {
|
||||||
|
StickerSets::const_iterator it = sets.constFind(order.at(i));
|
||||||
|
if (it != sets.cend()) {
|
||||||
|
bool disabled = (it->flags & MTPDstickerSet::flag_disabled);
|
||||||
|
|
||||||
|
DocumentData *sticker = it->stickers.isEmpty() ? 0 : it->stickers.at(0);
|
||||||
|
int32 pixw = 0, pixh = 0;
|
||||||
|
if (sticker) {
|
||||||
|
pixw = sticker->thumb->width();
|
||||||
|
pixh = sticker->thumb->height();
|
||||||
|
if (pixw > st::contactsPhotoSize) {
|
||||||
|
if (pixw > pixh) {
|
||||||
|
pixh = (pixh * st::contactsPhotoSize) / pixw;
|
||||||
|
pixw = st::contactsPhotoSize;
|
||||||
|
} else {
|
||||||
|
pixw = (pixw * st::contactsPhotoSize) / pixh;
|
||||||
|
pixh = st::contactsPhotoSize;
|
||||||
|
}
|
||||||
|
} else if (pixh > st::contactsPhotoSize) {
|
||||||
|
pixw = (pixw * st::contactsPhotoSize) / pixh;
|
||||||
|
pixh = st::contactsPhotoSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString title = it->title;
|
||||||
|
int32 titleWidth = st::contactsNameFont->width(title);
|
||||||
|
if (titleWidth > namew) {
|
||||||
|
title = st::contactsNameFont->elided(title, namew);
|
||||||
|
}
|
||||||
|
bool official = (it->flags & MTPDstickerSet::flag_official);
|
||||||
|
(disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, official, disabled, pixw, pixh));
|
||||||
|
_animStartTimes.push_back(0);
|
||||||
|
if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_flag_NOT_LOADED)) {
|
||||||
|
App::api()->scheduleStickerSetRequest(it->id, it->access);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
App::api()->requestStickerSets();
|
||||||
|
_rows = rows + rowsDisabled;
|
||||||
|
resize(width(), _itemsTop + _rows.size() * _rowHeight + st::membersPadding.bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<uint64> StickersInner::getOrder() const {
|
||||||
|
QVector<uint64> result;
|
||||||
|
result.reserve(_rows.size());
|
||||||
|
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
|
||||||
|
if (_rows.at(i)->disabled) {
|
||||||
|
StickerSets::const_iterator it = cStickerSets().constFind(_rows.at(i)->id);
|
||||||
|
if (it == cStickerSets().cend() || !(it->flags & MTPDstickerSet::flag_official)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push_back(_rows.at(i)->id);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<uint64> StickersInner::getDisabledSets() const {
|
||||||
|
QVector<uint64> result;
|
||||||
|
result.reserve(_rows.size());
|
||||||
|
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
|
||||||
|
if (_rows.at(i)->disabled) {
|
||||||
|
result.push_back(_rows.at(i)->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::setVisibleScrollbar(int32 width) {
|
||||||
|
_scrollbar = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
StickersInner::~StickersInner() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
StickersBox::StickersBox() : ItemListBox(st::boxScroll)
|
||||||
|
, _save(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||||
|
, _reorderRequest(0)
|
||||||
|
, _topShadow(this, st::contactsAboutShadow)
|
||||||
|
, _bottomShadow(this)
|
||||||
|
, _scrollDelta(0)
|
||||||
|
, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPhotoSize - st::contactsPadding.left() - st::contactsPadding.right())
|
||||||
|
, _about(st::boxTextFont, lang(lng_stickers_reorder), _defaultOptions, _aboutWidth)
|
||||||
|
, _aboutHeight(st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom()) {
|
||||||
|
ItemListBox::init(&_inner, st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom(), st::boxTitleHeight + _aboutHeight);
|
||||||
|
setMaxHeight(snap(countHeight(), int32(st::sessionsHeight), int32(st::boxMaxListHeight)));
|
||||||
|
|
||||||
|
connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated()));
|
||||||
|
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||||
|
|
||||||
|
connect(&_inner, SIGNAL(checkDraggingScroll(int)), this, SLOT(onCheckDraggingScroll(int)));
|
||||||
|
connect(&_inner, SIGNAL(noDraggingScroll()), this, SLOT(onNoDraggingScroll()));
|
||||||
|
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(onUpdateSelected()));
|
||||||
|
connect(&_scrollTimer, SIGNAL(timeout()), this, SLOT(onScrollTimer()));
|
||||||
|
_scrollTimer.setSingleShot(false);
|
||||||
|
|
||||||
|
onStickersUpdated();
|
||||||
|
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 StickersBox::countHeight() const {
|
||||||
|
return st::boxTitleHeight + _aboutHeight + _inner.height() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::disenableDone(const MTPBool & result, mtpRequestId req) {
|
||||||
|
_disenableRequests.remove(req);
|
||||||
|
if (_disenableRequests.isEmpty()) {
|
||||||
|
saveOrder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StickersBox::disenableFail(const RPCError &error, mtpRequestId req) {
|
||||||
|
if (mtpIsFlood(error)) return false;
|
||||||
|
_disenableRequests.remove(req);
|
||||||
|
if (_disenableRequests.isEmpty()) {
|
||||||
|
saveOrder();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::saveOrder() {
|
||||||
|
QVector<uint64> order = _inner.getOrder();
|
||||||
|
if (order.size() > 1) {
|
||||||
|
QVector<MTPlong> mtpOrder;
|
||||||
|
mtpOrder.reserve(order.size());
|
||||||
|
for (int32 i = 0, l = order.size(); i < l; ++i) {
|
||||||
|
mtpOrder.push_back(MTP_long(order.at(i)));
|
||||||
|
}
|
||||||
|
_reorderRequest = MTP::send(MTPmessages_ReorderStickerSets(MTP_vector<MTPlong>(mtpOrder)), rpcDone(&StickersBox::reorderDone), rpcFail(&StickersBox::reorderFail));
|
||||||
|
} else {
|
||||||
|
reorderDone(MTP_boolTrue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::reorderDone(const MTPBool &result) {
|
||||||
|
_reorderRequest = 0;
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StickersBox::reorderFail(const RPCError &result) {
|
||||||
|
if (mtpIsFlood(result)) return false;
|
||||||
|
_reorderRequest = 0;
|
||||||
|
cSetLastStickersUpdate(0);
|
||||||
|
App::main()->updateStickers();
|
||||||
|
onClose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
if (paint(p)) return;
|
||||||
|
|
||||||
|
paintTitle(p, lang(lng_stickers_packs));
|
||||||
|
p.translate(0, st::boxTitleHeight);
|
||||||
|
|
||||||
|
p.fillRect(0, 0, width(), _aboutHeight, st::contactsAboutBg);
|
||||||
|
p.setPen(st::stickersReorderFg);
|
||||||
|
_about.drawLeft(p, st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, width());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::closePressed() {
|
||||||
|
if (!_disenableRequests.isEmpty()) {
|
||||||
|
for (QMap<mtpRequestId, NullType>::const_iterator i = _disenableRequests.cbegin(), e = _disenableRequests.cend(); i != e; ++i) {
|
||||||
|
MTP::cancel(i.key());
|
||||||
|
}
|
||||||
|
_disenableRequests.clear();
|
||||||
|
cSetLastStickersUpdate(0);
|
||||||
|
App::main()->updateStickers();
|
||||||
|
} else if (_reorderRequest) {
|
||||||
|
MTP::cancel(_reorderRequest);
|
||||||
|
_reorderRequest = 0;
|
||||||
|
cSetLastStickersUpdate(0);
|
||||||
|
App::main()->updateStickers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
ItemListBox::resizeEvent(e);
|
||||||
|
_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());
|
||||||
|
_inner.resize(width(), _inner.height());
|
||||||
|
_topShadow.setGeometry(0, st::boxTitleHeight + _aboutHeight, width(), st::lineWidth);
|
||||||
|
_bottomShadow.setGeometry(0, height() - st::boxButtonPadding.bottom() - _save.height() - st::boxButtonPadding.top() - st::lineWidth, width(), st::lineWidth);
|
||||||
|
_inner.setVisibleScrollbar((_scroll.scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::onStickersUpdated() {
|
||||||
|
_inner.rebuild();
|
||||||
|
setMaxHeight(snap(countHeight(), int32(st::sessionsHeight), int32(st::boxMaxListHeight)));
|
||||||
|
_inner.setVisibleScrollbar((_scroll.scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::onCheckDraggingScroll(int localY) {
|
||||||
|
if (localY < _scroll.scrollTop()) {
|
||||||
|
_scrollDelta = localY - _scroll.scrollTop();
|
||||||
|
} else if (localY >= _scroll.scrollTop() + _scroll.height()) {
|
||||||
|
_scrollDelta = localY - _scroll.scrollTop() - _scroll.height() + 1;
|
||||||
|
} else {
|
||||||
|
_scrollDelta = 0;
|
||||||
|
}
|
||||||
|
if (_scrollDelta) {
|
||||||
|
_scrollTimer.start(15);
|
||||||
|
} else {
|
||||||
|
_scrollTimer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::onNoDraggingScroll() {
|
||||||
|
_scrollTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::onScrollTimer() {
|
||||||
|
int32 d = (_scrollDelta > 0) ? qMin(_scrollDelta * 3 / 20 + 1, int32(MaxScrollSpeed)) : qMax(_scrollDelta * 3 / 20 - 1, -int32(MaxScrollSpeed));
|
||||||
|
_scroll.scrollToY(_scroll.scrollTop() + d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::onSave() {
|
||||||
|
if (!_inner.savingStart()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool writeRecent = false;
|
||||||
|
RecentStickerPack &recent(cGetRecentStickers());
|
||||||
|
StickerSets &sets(cRefStickerSets());
|
||||||
|
|
||||||
|
QVector<uint64> reorder = _inner.getOrder(), disabled = _inner.getDisabledSets();
|
||||||
|
for (int32 i = 0, l = disabled.size(); i < l; ++i) {
|
||||||
|
StickerSets::iterator it = sets.find(disabled.at(i));
|
||||||
|
if (it != sets.cend()) {
|
||||||
|
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
||||||
|
if (it->stickers.indexOf(i->first) >= 0) {
|
||||||
|
i = recent.erase(i);
|
||||||
|
writeRecent = true;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(it->flags & MTPDstickerSet::flag_disabled)) {
|
||||||
|
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
|
||||||
|
if (it->flags & MTPDstickerSet::flag_official) {
|
||||||
|
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
||||||
|
it->flags |= MTPDstickerSet::flag_disabled;
|
||||||
|
} else {
|
||||||
|
_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
||||||
|
int32 removeIndex = cStickerSetsOrder().indexOf(it->id);
|
||||||
|
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
|
||||||
|
sets.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StickerSetsOrder &order(cRefStickerSetsOrder());
|
||||||
|
order.clear();
|
||||||
|
for (int32 i = 0, l = reorder.size(); i < l; ++i) {
|
||||||
|
StickerSets::iterator it = sets.find(reorder.at(i));
|
||||||
|
if (it != sets.cend()) {
|
||||||
|
if ((it->flags & MTPDstickerSet::flag_disabled) && !disabled.contains(it->id)) {
|
||||||
|
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
|
||||||
|
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
||||||
|
it->flags &= ~MTPDstickerSet::flag_disabled;
|
||||||
|
}
|
||||||
|
order.push_back(reorder.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (StickerSets::iterator it = sets.begin(); it != sets.cend();) {
|
||||||
|
if (it->id == CustomStickerSetId || it->id == RecentStickerSetId || order.contains(it->id)) {
|
||||||
|
++it;
|
||||||
|
} else {
|
||||||
|
it = sets.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cSetStickersHash(stickersCountHash());
|
||||||
|
Local::writeStickers();
|
||||||
|
if (writeRecent) Local::writeUserSettings();
|
||||||
|
emit App::main()->stickersUpdated();
|
||||||
|
|
||||||
|
if (_disenableRequests.isEmpty()) {
|
||||||
|
saveOrder();
|
||||||
|
} else {
|
||||||
|
MTP::sendAnything();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::hideAll() {
|
||||||
|
_save.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
_topShadow.hide();
|
||||||
|
_bottomShadow.hide();
|
||||||
|
ItemListBox::hideAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersBox::showAll() {
|
||||||
|
_save.show();
|
||||||
|
_cancel.show();
|
||||||
|
_topShadow.show();
|
||||||
|
_bottomShadow.show();
|
||||||
|
ItemListBox::showAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 stickerPacksCount(bool includeDisabledOfficial) {
|
||||||
|
int32 result = 0;
|
||||||
|
const StickerSetsOrder &order(cStickerSetsOrder());
|
||||||
|
const StickerSets &sets(cStickerSets());
|
||||||
|
for (int32 i = 0, l = order.size(); i < l; ++i) {
|
||||||
|
StickerSets::const_iterator it = sets.constFind(order.at(i));
|
||||||
|
if (it != sets.cend()) {
|
||||||
|
if (!(it->flags & MTPDstickerSet::flag_disabled) || ((it->flags & MTPDstickerSet::flag_official) && includeDisabledOfficial)) {
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -106,3 +106,145 @@ private:
|
||||||
BoxButton _add, _share, _cancel, _done;
|
BoxButton _add, _share, _cancel, _done;
|
||||||
QString _title;
|
QString _title;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StickersInner : public TWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
StickersInner();
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
void mousePressEvent(QMouseEvent *e);
|
||||||
|
void mouseMoveEvent(QMouseEvent *e);
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e);
|
||||||
|
|
||||||
|
void rebuild();
|
||||||
|
bool savingStart() {
|
||||||
|
if (_saving) return false;
|
||||||
|
_saving = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<uint64> getOrder() const;
|
||||||
|
QVector<uint64> getDisabledSets() const;
|
||||||
|
|
||||||
|
void setVisibleScrollbar(int32 width);
|
||||||
|
|
||||||
|
~StickersInner();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void checkDraggingScroll(int localY);
|
||||||
|
void noDraggingScroll();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onUpdateSelected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool animStep_shifting(float64 ms);
|
||||||
|
void paintRow(Painter &p, int32 index);
|
||||||
|
void clear();
|
||||||
|
void setRemoveSel(int32 removeSel);
|
||||||
|
float64 aboveShadowOpacity() const;
|
||||||
|
void updateAnimatedRegions();
|
||||||
|
bool updateAnimatedValues();
|
||||||
|
|
||||||
|
int32 _rowHeight;
|
||||||
|
struct StickerSetRow {
|
||||||
|
StickerSetRow(uint64 id, DocumentData *sticker, int32 count, const QString &title, bool official, bool disabled, int32 pixw, int32 pixh) : id(id)
|
||||||
|
, sticker(sticker)
|
||||||
|
, count(count)
|
||||||
|
, title(title)
|
||||||
|
, official(official)
|
||||||
|
, disabled(disabled)
|
||||||
|
, pixw(pixw)
|
||||||
|
, pixh(pixh)
|
||||||
|
, yadd(0, 0) {
|
||||||
|
}
|
||||||
|
uint64 id;
|
||||||
|
DocumentData *sticker;
|
||||||
|
int32 count;
|
||||||
|
QString title;
|
||||||
|
bool official, disabled;
|
||||||
|
int32 pixw, pixh;
|
||||||
|
anim::ivalue yadd;
|
||||||
|
};
|
||||||
|
typedef QList<StickerSetRow*> StickerSetRows;
|
||||||
|
StickerSetRows _rows;
|
||||||
|
QList<uint64> _animStartTimes;
|
||||||
|
uint64 _aboveShadowFadeStart;
|
||||||
|
anim::fvalue _aboveShadowFadeOpacity;
|
||||||
|
Animation _a_shifting;
|
||||||
|
|
||||||
|
int32 _itemsTop;
|
||||||
|
|
||||||
|
bool _saving;
|
||||||
|
|
||||||
|
int32 _removeSel, _removeDown, _removeWidth, _returnWidth, _restoreWidth;
|
||||||
|
|
||||||
|
QPoint _mouse;
|
||||||
|
int32 _selected;
|
||||||
|
QPoint _dragStart;
|
||||||
|
int32 _started, _dragging, _above;
|
||||||
|
|
||||||
|
BoxShadow _aboveShadow;
|
||||||
|
|
||||||
|
int32 _scrollbar;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StickersBox : public ItemListBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
StickersBox();
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
|
||||||
|
void closePressed();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onStickersUpdated();
|
||||||
|
|
||||||
|
void onCheckDraggingScroll(int localY);
|
||||||
|
void onNoDraggingScroll();
|
||||||
|
void onScrollTimer();
|
||||||
|
|
||||||
|
void onSave();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void hideAll();
|
||||||
|
void showAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int32 countHeight() const;
|
||||||
|
|
||||||
|
void disenableDone(const MTPBool &result, mtpRequestId req);
|
||||||
|
bool disenableFail(const RPCError &error, mtpRequestId req);
|
||||||
|
void reorderDone(const MTPBool &result);
|
||||||
|
bool reorderFail(const RPCError &result);
|
||||||
|
void saveOrder();
|
||||||
|
|
||||||
|
StickersInner _inner;
|
||||||
|
BoxButton _save, _cancel;
|
||||||
|
QMap<mtpRequestId, NullType> _disenableRequests;
|
||||||
|
mtpRequestId _reorderRequest;
|
||||||
|
PlainShadow _topShadow;
|
||||||
|
ScrollableBoxShadow _bottomShadow;
|
||||||
|
|
||||||
|
QTimer _scrollTimer;
|
||||||
|
int32 _scrollDelta;
|
||||||
|
|
||||||
|
int32 _aboutWidth;
|
||||||
|
Text _about;
|
||||||
|
int32 _aboutHeight;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int32 stickerPacksCount(bool includeDisabledOfficial = false);
|
||||||
|
|
|
@ -20,9 +20,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
static const int32 AppVersion = 9013;
|
static const int32 AppVersion = 9015;
|
||||||
static const wchar_t *AppVersionStr = L"0.9.13";
|
static const wchar_t *AppVersionStr = L"0.9.15";
|
||||||
static const bool DevVersion = false;
|
static const bool DevVersion = false;
|
||||||
|
//#define BETA_VERSION (9014003ULL) // just comment this line to build public version
|
||||||
|
|
||||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||||
static const wchar_t *AppName = L"Telegram Desktop";
|
static const wchar_t *AppName = L"Telegram Desktop";
|
||||||
|
@ -58,6 +59,8 @@ enum {
|
||||||
|
|
||||||
MTPDebugBufferSize = 1024 * 1024, // 1 mb start size
|
MTPDebugBufferSize = 1024 * 1024, // 1 mb start size
|
||||||
|
|
||||||
|
MaxUsersPerInvite = 100, // max users in one super group invite request
|
||||||
|
|
||||||
MTPPingDelayDisconnect = 60, // 1 min
|
MTPPingDelayDisconnect = 60, // 1 min
|
||||||
MTPPingSendAfterAuto = 30, // send new ping starting from 30 seconds (add to existing container)
|
MTPPingSendAfterAuto = 30, // send new ping starting from 30 seconds (add to existing container)
|
||||||
MTPPingSendAfter = 45, // send new ping after 45 seconds without ping
|
MTPPingSendAfter = 45, // send new ping after 45 seconds without ping
|
||||||
|
@ -67,7 +70,7 @@ enum {
|
||||||
MaxSelectedItems = 100,
|
MaxSelectedItems = 100,
|
||||||
|
|
||||||
MaxPhoneCodeLength = 4, // max length of country phone code
|
MaxPhoneCodeLength = 4, // max length of country phone code
|
||||||
MaxPhoneTailLength = 18, // rest of the phone number, without country code (seen 12 at least)
|
MaxPhoneTailLength = 32, // rest of the phone number, without country code (seen 12 at least), need more for service numbers
|
||||||
|
|
||||||
MaxScrollSpeed = 37, // 37px per 15ms while select-by-drag
|
MaxScrollSpeed = 37, // 37px per 15ms while select-by-drag
|
||||||
FingerAccuracyThreshold = 3, // touch flick ignore 3px
|
FingerAccuracyThreshold = 3, // touch flick ignore 3px
|
||||||
|
@ -265,6 +268,18 @@ static const int32 ApiId = 17349;
|
||||||
static const char *ApiHash = "344583e45741c457fe1862106095a5eb";
|
static const char *ApiHash = "344583e45741c457fe1862106095a5eb";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef BETA_VERSION
|
||||||
|
#define BETA_VERSION (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined CUSTOM_API_ID) && (BETA_VERSION > 0)
|
||||||
|
#include "../../../TelegramPrivate/beta_private.h" // private key for downloading closed betas
|
||||||
|
#else
|
||||||
|
static const char *BetaPrivateKey = "";
|
||||||
|
#undef BETA_VERSION
|
||||||
|
#define BETA_VERSION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
inline const char *cApiDeviceModel() {
|
inline const char *cApiDeviceModel() {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
return "PC";
|
return "PC";
|
||||||
|
|
|
@ -28,6 +28,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "boxes/addcontactbox.h"
|
#include "boxes/addcontactbox.h"
|
||||||
#include "boxes/contactsbox.h"
|
#include "boxes/contactsbox.h"
|
||||||
|
#include "boxes/confirmbox.h"
|
||||||
|
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
|
@ -53,7 +54,10 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
|
||||||
, _cancelSearchInPeer(this, st::btnCancelSearch)
|
, _cancelSearchInPeer(this, st::btnCancelSearch)
|
||||||
, _overDelete(false)
|
, _overDelete(false)
|
||||||
, _searchInPeer(0)
|
, _searchInPeer(0)
|
||||||
, _searchInMigrated(0) {
|
, _searchInMigrated(0)
|
||||||
|
, _menuPeer(0)
|
||||||
|
, _menuActionPeer(0)
|
||||||
|
, _menu(0) {
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
connect(main, SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
|
connect(main, SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)));
|
||||||
connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*)));
|
connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*)));
|
||||||
|
@ -61,7 +65,7 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
|
||||||
connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
|
connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
|
||||||
connect(&_cancelSearchInPeer, SIGNAL(clicked()), this, SIGNAL(cancelSearchInPeer()));
|
connect(&_cancelSearchInPeer, SIGNAL(clicked()), this, SIGNAL(cancelSearchInPeer()));
|
||||||
_cancelSearchInPeer.hide();
|
_cancelSearchInPeer.hide();
|
||||||
refresh(false);
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 DialogsInner::filteredOffset() const {
|
int32 DialogsInner::filteredOffset() const {
|
||||||
|
@ -91,7 +95,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
|
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
int32 otherStart = dialogs.list.count * st::dlgHeight;
|
int32 otherStart = dialogs.list.count * st::dlgHeight;
|
||||||
PeerData *active = App::main()->activePeer(), *selected = sel ? sel->history->peer : 0;
|
PeerData *active = App::main()->activePeer(), *selected = _menuPeer ? _menuPeer : (sel ? sel->history->peer : 0);
|
||||||
if (otherStart) {
|
if (otherStart) {
|
||||||
dialogs.list.paint(p, fullWidth(), r.top(), r.top() + r.height(), active, selected, paintingOther);
|
dialogs.list.paint(p, fullWidth(), r.top(), r.top() + r.height(), active, selected, paintingOther);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +164,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
MsgId actId = App::main()->activeMsgId();
|
MsgId actId = App::main()->activeMsgId();
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
bool active = ((_filterResults[from]->history->peer == act) || (_filterResults[from]->history->peer->migrateTo() && _filterResults[from]->history->peer->migrateTo() == act)) && !actId;
|
bool active = ((_filterResults[from]->history->peer == act) || (_filterResults[from]->history->peer->migrateTo() && _filterResults[from]->history->peer->migrateTo() == act)) && !actId;
|
||||||
bool selected = (from == _filteredSel);
|
bool selected = (from == _filteredSel) || (_filterResults[from]->history->peer == _menuPeer);
|
||||||
_filterResults[from]->paint(p, w, active, selected, paintingOther);
|
_filterResults[from]->paint(p, w, active, selected, paintingOther);
|
||||||
p.translate(0, st::dlgHeight);
|
p.translate(0, st::dlgHeight);
|
||||||
}
|
}
|
||||||
|
@ -461,6 +465,9 @@ void DialogsInner::createDialog(History *history) {
|
||||||
|
|
||||||
void DialogsInner::removeDialog(History *history) {
|
void DialogsInner::removeDialog(History *history) {
|
||||||
if (!history) return;
|
if (!history) return;
|
||||||
|
if (history->peer == _menuPeer && _menu) {
|
||||||
|
_menu->deleteLater();
|
||||||
|
}
|
||||||
if (sel && sel->history == history) {
|
if (sel && sel->history == history) {
|
||||||
sel = 0;
|
sel = 0;
|
||||||
}
|
}
|
||||||
|
@ -549,13 +556,26 @@ void DialogsInner::enterEvent(QEvent *e) {
|
||||||
onUpdateSelected(true);
|
onUpdateSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::updateSelectedRow() {
|
void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (sel) {
|
if (peer) {
|
||||||
|
if (History *h = App::historyLoaded(peer->id)) {
|
||||||
|
if (h->dialogs.contains(0)) {
|
||||||
|
update(0, h->dialogs.value(0)->pos * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sel) {
|
||||||
update(0, sel->pos * st::dlgHeight, fullWidth(), st::dlgHeight);
|
update(0, sel->pos * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (_hashtagSel >= 0) {
|
if (peer) {
|
||||||
|
for (int32 i = 0, l = _filterResults.size(); i != l; ++i) {
|
||||||
|
if (_filterResults.at(i)->history->peer == peer) {
|
||||||
|
update(0, filteredOffset() + i * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_hashtagSel >= 0) {
|
||||||
update(0, _hashtagSel * st::mentionHeight, fullWidth(), st::mentionHeight);
|
update(0, _hashtagSel * st::mentionHeight, fullWidth(), st::mentionHeight);
|
||||||
} else if (_filteredSel >= 0) {
|
} else if (_filteredSel >= 0) {
|
||||||
update(0, filteredOffset() + _filteredSel * st::dlgHeight, fullWidth(), st::dlgHeight);
|
update(0, filteredOffset() + _filteredSel * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
|
@ -579,6 +599,148 @@ void DialogsInner::leaveEvent(QEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
|
if (_menu) {
|
||||||
|
_menu->deleteLater();
|
||||||
|
_menu = 0;
|
||||||
|
}
|
||||||
|
if (_menuPeer) {
|
||||||
|
updateSelectedRow(_menuPeer);
|
||||||
|
_menuPeer = 0;
|
||||||
|
disconnect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->reason() == QContextMenuEvent::Mouse) {
|
||||||
|
lastMousePos = e->globalPos();
|
||||||
|
selByMouse = true;
|
||||||
|
onUpdateSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
History *history = 0;
|
||||||
|
if (_state == DefaultState) {
|
||||||
|
if (sel) history = sel->history;
|
||||||
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
|
if (_filteredSel >= 0 && _filteredSel < _filterResults.size()) {
|
||||||
|
history = _filterResults[_filteredSel]->history;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!history) return;
|
||||||
|
_menuPeer = history->peer;
|
||||||
|
|
||||||
|
_menu = new PopupMenu();
|
||||||
|
_menu->addAction(lang((_menuPeer->isChat() || _menuPeer->isMegagroup()) ? lng_context_view_group : (_menuPeer->isUser() ? lng_context_view_profile : lng_context_view_channel)), this, SLOT(onContextProfile()))->setEnabled(true);
|
||||||
|
_menu->addAction(lang(menuPeerMuted() ? lng_enable_notifications_from_tray : lng_disable_notifications_from_tray), this, SLOT(onContextToggleNotifications()))->setEnabled(true);
|
||||||
|
_menu->addAction(lang(lng_profile_search_messages), this, SLOT(onContextSearch()))->setEnabled(true);
|
||||||
|
if (_menuPeer->isUser()) {
|
||||||
|
_menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true);
|
||||||
|
_menu->addAction(lang(lng_profile_delete_conversation), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true);
|
||||||
|
if (_menuPeer->asUser()->access != UserNoAccess) {
|
||||||
|
_menu->addAction(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true);
|
||||||
|
connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
||||||
|
}
|
||||||
|
} else if (_menuPeer->isChat()) {
|
||||||
|
_menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true);
|
||||||
|
_menu->addAction(lang(lng_profile_clear_and_exit), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true);
|
||||||
|
} else if (_menuPeer->isChannel() && _menuPeer->asChannel()->amIn() && !_menuPeer->asChannel()->amCreator()) {
|
||||||
|
_menu->addAction(lang(_menuPeer->isMegagroup() ? lng_profile_leave_group : lng_profile_leave_channel), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(_menu, SIGNAL(destroyed(QObject*)), this, SLOT(onMenuDestroyed(QObject*)));
|
||||||
|
_menu->popup(e->globalPos());
|
||||||
|
e->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DialogsInner::menuPeerMuted() {
|
||||||
|
return _menuPeer && _menuPeer->notify != EmptyNotifySettings && _menuPeer->notify != UnknownNotifySettings && _menuPeer->notify->mute >= unixtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextProfile() {
|
||||||
|
if (!_menuPeer) return;
|
||||||
|
App::main()->showPeerProfile(_menuPeer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextToggleNotifications() {
|
||||||
|
if (!_menuPeer) return;
|
||||||
|
App::main()->updateNotifySetting(_menuPeer, menuPeerMuted());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextSearch() {
|
||||||
|
if (!_menuPeer) return;
|
||||||
|
App::main()->searchInPeer(_menuPeer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextClearHistory() {
|
||||||
|
if (!_menuPeer || _menuPeer->isChannel()) return;
|
||||||
|
|
||||||
|
_menuActionPeer = _menuPeer;
|
||||||
|
ConfirmBox *box = new ConfirmBox(_menuPeer->isUser() ? lng_sure_delete_history(lt_contact, _menuPeer->name) : lng_sure_delete_group_history(lt_group, _menuPeer->name), lang(lng_box_delete), st::attentionBoxButton);
|
||||||
|
connect(box, SIGNAL(confirmed()), this, SLOT(onContextClearHistorySure()));
|
||||||
|
App::showLayer(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextClearHistorySure() {
|
||||||
|
if (!_menuActionPeer || _menuActionPeer->isChannel()) return;
|
||||||
|
App::wnd()->hideLayer();
|
||||||
|
App::main()->clearHistory(_menuActionPeer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextDeleteAndLeave() {
|
||||||
|
if (!_menuPeer) return;
|
||||||
|
|
||||||
|
_menuActionPeer = _menuPeer;
|
||||||
|
ConfirmBox *box = new ConfirmBox(_menuPeer->isUser() ? lng_sure_delete_history(lt_contact, _menuPeer->name) : (_menuPeer->isChat() ? lng_sure_delete_and_exit(lt_group, _menuPeer->name) : lang(_menuPeer->isMegagroup() ? lng_sure_leave_group : lng_sure_leave_channel)), lang(_menuPeer->isUser() ? lng_box_delete : lng_box_leave), _menuPeer->isChannel() ? st::defaultBoxButton : st::attentionBoxButton);
|
||||||
|
connect(box, SIGNAL(confirmed()), this, SLOT(onContextDeleteAndLeaveSure()));
|
||||||
|
App::wnd()->showLayer(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextDeleteAndLeaveSure() {
|
||||||
|
if (!_menuActionPeer) return;
|
||||||
|
|
||||||
|
App::wnd()->hideLayer();
|
||||||
|
App::main()->showDialogs();
|
||||||
|
if (_menuActionPeer->isUser()) {
|
||||||
|
App::main()->deleteConversation(_menuActionPeer);
|
||||||
|
} else if (_menuActionPeer->isChat()) {
|
||||||
|
MTP::send(MTPmessages_DeleteChatUser(_menuActionPeer->asChat()->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _menuActionPeer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _menuActionPeer));
|
||||||
|
} else if (_menuActionPeer->isChannel()) {
|
||||||
|
if (_menuActionPeer->migrateFrom()) {
|
||||||
|
App::main()->deleteConversation(_menuActionPeer->migrateFrom());
|
||||||
|
}
|
||||||
|
MTP::send(MTPchannels_LeaveChannel(_menuActionPeer->asChannel()->inputChannel), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onContextToggleBlock() {
|
||||||
|
if (!_menuPeer || !_menuPeer->isUser()) return;
|
||||||
|
if (_menuPeer->asUser()->blocked == UserIsBlocked) {
|
||||||
|
MTP::send(MTPcontacts_Unblock(_menuPeer->asUser()->inputUser), rpcDone(&DialogsInner::contextBlockDone, qMakePair(_menuPeer->asUser(), false)));
|
||||||
|
} else {
|
||||||
|
MTP::send(MTPcontacts_Block(_menuPeer->asUser()->inputUser), rpcDone(&DialogsInner::contextBlockDone, qMakePair(_menuPeer->asUser(), true)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::contextBlockDone(QPair<UserData*, bool> data, const MTPBool &result) {
|
||||||
|
data.first->blocked = data.second ? UserIsBlocked : UserIsNotBlocked;
|
||||||
|
emit App::main()->peerUpdated(data.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::onMenuDestroyed(QObject *obj) {
|
||||||
|
if (_menu == obj) {
|
||||||
|
_menu = 0;
|
||||||
|
if (_menuPeer) {
|
||||||
|
updateSelectedRow(_menuPeer);
|
||||||
|
_menuPeer = 0;
|
||||||
|
disconnect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
||||||
|
}
|
||||||
|
lastMousePos = QCursor::pos();
|
||||||
|
if (rect().contains(mapFromGlobal(lastMousePos))) {
|
||||||
|
selByMouse = true;
|
||||||
|
setMouseTracking(true);
|
||||||
|
onUpdateSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsInner::onParentGeometryChanged() {
|
void DialogsInner::onParentGeometryChanged() {
|
||||||
lastMousePos = QCursor::pos();
|
lastMousePos = QCursor::pos();
|
||||||
if (rect().contains(mapFromGlobal(lastMousePos))) {
|
if (rect().contains(mapFromGlobal(lastMousePos))) {
|
||||||
|
@ -763,6 +925,18 @@ void DialogsInner::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsInner::updateNotifySettings(PeerData *peer) {
|
||||||
|
if (_menu && _menuPeer == peer && _menu->actions().size() > 1) {
|
||||||
|
_menu->actions().at(1)->setText(lang(menuPeerMuted() ? lng_enable_notifications_from_tray : lng_disable_notifications_from_tray));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::peerUpdated(PeerData *peer) {
|
||||||
|
if (_menu && _menuPeer == peer && _menuPeer->isUser() && _menu->actions().size() > 5) {
|
||||||
|
_menu->actions().at(5)->setText(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
|
PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
|
||||||
lastMousePos = globalPos;
|
lastMousePos = globalPos;
|
||||||
selByMouse = true;
|
selByMouse = true;
|
||||||
|
@ -1008,7 +1182,6 @@ void DialogsInner::setState(State newState) {
|
||||||
_filteredSel = -1;
|
_filteredSel = -1;
|
||||||
}
|
}
|
||||||
onFilterUpdate(_filter, true);
|
onFilterUpdate(_filter, true);
|
||||||
refresh(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogsInner::State DialogsInner::state() const {
|
DialogsInner::State DialogsInner::state() const {
|
||||||
|
@ -1681,7 +1854,9 @@ bool DialogsWidget::animStep_show(float64 ms) {
|
||||||
|
|
||||||
_scroll.show();
|
_scroll.show();
|
||||||
_filter.show();
|
_filter.show();
|
||||||
onFilterUpdate(true);
|
_a_show.stop();
|
||||||
|
|
||||||
|
onFilterUpdate();
|
||||||
activate();
|
activate();
|
||||||
|
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
if (App::app()) App::app()->mtpUnpause();
|
||||||
|
@ -1708,6 +1883,10 @@ void DialogsWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||||
_inner.itemReplaced(oldItem, newItem);
|
_inner.itemReplaced(oldItem, newItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsWidget::updateNotifySettings(PeerData *peer) {
|
||||||
|
_inner.updateNotifySettings(peer);
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
|
void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
|
||||||
for (QVector<MTPDialog>::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) {
|
for (QVector<MTPDialog>::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) {
|
||||||
switch (i->type()) {
|
switch (i->type()) {
|
||||||
|
|
|
@ -31,7 +31,7 @@ enum DialogsSearchRequestType {
|
||||||
DialogsSearchMigratedFromOffset,
|
DialogsSearchMigratedFromOffset,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DialogsInner : public SplittedWidget {
|
class DialogsInner : public SplittedWidget, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -59,6 +59,7 @@ public:
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
void enterEvent(QEvent *e);
|
void enterEvent(QEvent *e);
|
||||||
void leaveEvent(QEvent *e);
|
void leaveEvent(QEvent *e);
|
||||||
|
void contextMenuEvent(QContextMenuEvent *e);
|
||||||
|
|
||||||
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const;
|
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const;
|
||||||
void searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const;
|
void searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const;
|
||||||
|
@ -120,6 +121,8 @@ public:
|
||||||
|
|
||||||
PeerData *updateFromParentDrag(QPoint globalPos);
|
PeerData *updateFromParentDrag(QPoint globalPos);
|
||||||
|
|
||||||
|
void updateNotifySettings(PeerData *peer);
|
||||||
|
|
||||||
~DialogsInner();
|
~DialogsInner();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -130,6 +133,19 @@ public slots:
|
||||||
void onPeerPhotoChanged(PeerData *peer);
|
void onPeerPhotoChanged(PeerData *peer);
|
||||||
void onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow);
|
void onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow);
|
||||||
|
|
||||||
|
void onContextProfile();
|
||||||
|
void onContextToggleNotifications();
|
||||||
|
void onContextSearch();
|
||||||
|
void onContextClearHistory();
|
||||||
|
void onContextClearHistorySure();
|
||||||
|
void onContextDeleteAndLeave();
|
||||||
|
void onContextDeleteAndLeaveSure();
|
||||||
|
void onContextToggleBlock();
|
||||||
|
|
||||||
|
void onMenuDestroyed(QObject*);
|
||||||
|
|
||||||
|
void peerUpdated(PeerData *peer);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
||||||
|
@ -147,7 +163,9 @@ protected:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void clearSearchResults(bool clearPeople = true);
|
void clearSearchResults(bool clearPeople = true);
|
||||||
void updateSelectedRow();
|
void updateSelectedRow(PeerData *peer = 0);
|
||||||
|
bool menuPeerMuted();
|
||||||
|
void contextBlockDone(QPair<UserData*, bool> data, const MTPBool &result);
|
||||||
|
|
||||||
DialogsIndexed dialogs;
|
DialogsIndexed dialogs;
|
||||||
DialogsIndexed contactsNoDialogs;
|
DialogsIndexed contactsNoDialogs;
|
||||||
|
@ -186,7 +204,9 @@ private:
|
||||||
|
|
||||||
bool _overDelete;
|
bool _overDelete;
|
||||||
|
|
||||||
PeerData *_searchInPeer, *_searchInMigrated;
|
PeerData *_searchInPeer, *_searchInMigrated, *_menuPeer, *_menuActionPeer;
|
||||||
|
|
||||||
|
PopupMenu *_menu;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -242,6 +262,8 @@ public:
|
||||||
void itemRemoved(HistoryItem *item);
|
void itemRemoved(HistoryItem *item);
|
||||||
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
|
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
|
||||||
|
|
||||||
|
void updateNotifySettings(PeerData *peer);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void cancelled();
|
void cancelled();
|
||||||
|
|
|
@ -30,6 +30,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
|
||||||
#include "boxes/confirmbox.h"
|
#include "boxes/confirmbox.h"
|
||||||
|
#include "boxes/stickersetbox.h"
|
||||||
|
|
||||||
Dropdown::Dropdown(QWidget *parent, const style::dropdown &st) : TWidget(parent),
|
Dropdown::Dropdown(QWidget *parent, const style::dropdown &st) : TWidget(parent),
|
||||||
_ignore(false), _selected(-1), _st(st), _width(_st.width), _hiding(false), a_opacity(0), _shadow(_st.shadow) {
|
_ignore(false), _selected(-1), _st(st), _width(_st.width), _hiding(false), a_opacity(0), _shadow(_st.shadow) {
|
||||||
|
@ -38,7 +39,7 @@ _ignore(false), _selected(-1), _st(st), _width(_st.width), _hiding(false), a_opa
|
||||||
_hideTimer.setSingleShot(true);
|
_hideTimer.setSingleShot(true);
|
||||||
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart()));
|
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart()));
|
||||||
|
|
||||||
if (cPlatform() == dbipMac) {
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1195,15 +1196,23 @@ void EmojiPanInner::showEmojiPack(DBIEmojiTab packIndex) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
StickerPanInner::StickerPanInner() : _maxHeight(st::emojiPanMaxHeight),
|
StickerPanInner::StickerPanInner() : TWidget()
|
||||||
_top(0), _selected(-1), _pressedSel(-1) {
|
, _top(0)
|
||||||
resize(st::emojiPanWidth - st::emojiScroll.width, countHeight());
|
, _selected(-1)
|
||||||
|
, _pressedSel(-1)
|
||||||
|
, _settings(this, lang(lng_stickers_you_have))
|
||||||
|
, _previewShown(false) {
|
||||||
|
setMaxHeight(st::emojiPanMaxHeight);
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setFocusPolicy(Qt::NoFocus);
|
setFocusPolicy(Qt::NoFocus);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
|
connect(&_settings, SIGNAL(clicked()), this, SLOT(onSettings()));
|
||||||
|
|
||||||
|
_previewTimer.setSingleShot(true);
|
||||||
|
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview()));
|
||||||
|
|
||||||
refreshStickers();
|
refreshStickers();
|
||||||
}
|
}
|
||||||
|
@ -1211,6 +1220,7 @@ _top(0), _selected(-1), _pressedSel(-1) {
|
||||||
void StickerPanInner::setMaxHeight(int32 h) {
|
void StickerPanInner::setMaxHeight(int32 h) {
|
||||||
_maxHeight = h;
|
_maxHeight = h;
|
||||||
resize(st::emojiPanWidth - st::emojiScroll.width, countHeight());
|
resize(st::emojiPanWidth - st::emojiScroll.width, countHeight());
|
||||||
|
_settings.moveToLeft((st::emojiPanWidth - _settings.width()) / 2, height() / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::setScrollTop(int top) {
|
void StickerPanInner::setScrollTop(int top) {
|
||||||
|
@ -1228,7 +1238,7 @@ int StickerPanInner::countHeight() {
|
||||||
if (i == _sets.size() - 1 && h < minLastH) h = minLastH;
|
if (i == _sets.size() - 1 && h < minLastH) h = minLastH;
|
||||||
result += h;
|
result += h;
|
||||||
}
|
}
|
||||||
return result + st::stickerPanPadding;
|
return qMax(minLastH, result) + st::stickerPanPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect StickerPanInner::stickerRect(int tab, int sel) {
|
QRect StickerPanInner::stickerRect(int tab, int sel) {
|
||||||
|
@ -1343,15 +1353,23 @@ void StickerPanInner::mousePressEvent(QMouseEvent *e) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
_pressedSel = _selected;
|
_pressedSel = _selected;
|
||||||
|
_previewTimer.start(QApplication::startDragTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
|
void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
_previewTimer.stop();
|
||||||
|
|
||||||
int32 pressed = _pressedSel;
|
int32 pressed = _pressedSel;
|
||||||
_pressedSel = -1;
|
_pressedSel = -1;
|
||||||
|
|
||||||
_lastMousePos = e->globalPos();
|
_lastMousePos = e->globalPos();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
|
if (_previewShown) {
|
||||||
|
_previewShown = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_selected < 0 || _selected != pressed) return;
|
if (_selected < 0 || _selected != pressed) return;
|
||||||
if (_selected >= MatrixRowShift * _sets.size()) {
|
if (_selected >= MatrixRowShift * _sets.size()) {
|
||||||
return;
|
return;
|
||||||
|
@ -1461,6 +1479,8 @@ void StickerPanInner::refreshStickers() {
|
||||||
int32 h = countHeight();
|
int32 h = countHeight();
|
||||||
if (h != height()) resize(width(), h);
|
if (h != height()) resize(width(), h);
|
||||||
|
|
||||||
|
_settings.setVisible(_sets.isEmpty());
|
||||||
|
|
||||||
emit refreshIcons();
|
emit refreshIcons();
|
||||||
|
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
@ -1512,7 +1532,7 @@ uint64 StickerPanInner::currentSet(int yOffset) const {
|
||||||
void StickerPanInner::appendSet(uint64 setId) {
|
void StickerPanInner::appendSet(uint64 setId) {
|
||||||
const StickerSets &sets(cStickerSets());
|
const StickerSets &sets(cStickerSets());
|
||||||
StickerSets::const_iterator it = sets.constFind(setId);
|
StickerSets::const_iterator it = sets.constFind(setId);
|
||||||
if (it == sets.cend() || it->stickers.isEmpty()) return;
|
if (it == sets.cend() || (it->flags & MTPDstickerSet::flag_disabled) || it->stickers.isEmpty()) return;
|
||||||
|
|
||||||
StickerPack pack;
|
StickerPack pack;
|
||||||
pack.reserve(it->stickers.size());
|
pack.reserve(it->stickers.size());
|
||||||
|
@ -1630,7 +1650,7 @@ void StickerPanInner::refreshPanels(QVector<EmojiPanel*> &panels) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::updateSelected() {
|
void StickerPanInner::updateSelected() {
|
||||||
if (_pressedSel >= 0) return;
|
if (_pressedSel >= 0 && !_previewShown) return;
|
||||||
|
|
||||||
int32 selIndex = -1;
|
int32 selIndex = -1;
|
||||||
QPoint p(mapFromGlobal(_lastMousePos));
|
QPoint p(mapFromGlobal(_lastMousePos));
|
||||||
|
@ -1707,9 +1727,29 @@ void StickerPanInner::updateSelected() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_selected = selIndex;
|
_selected = selIndex;
|
||||||
|
if (_pressedSel >= 0 && _selected >= 0 && _pressedSel != _selected) {
|
||||||
|
_pressedSel = _selected;
|
||||||
|
if (newSel >= 0 && xNewSel < 0) {
|
||||||
|
Ui::showStickerPreview(_sets.at(newSelTab).pack.at(newSel % MatrixRowShift));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (startanim) anim::start(this);
|
if (startanim) anim::start(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickerPanInner::onSettings() {
|
||||||
|
App::showLayer(new StickersBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerPanInner::onPreview() {
|
||||||
|
if (_pressedSel >= 0 && _pressedSel < MatrixRowShift * _sets.size()) {
|
||||||
|
int tab = (_pressedSel / MatrixRowShift), sel = _pressedSel % MatrixRowShift;
|
||||||
|
if (sel < _sets.at(tab).pack.size()) {
|
||||||
|
Ui::showStickerPreview(_sets.at(tab).pack.at(sel));
|
||||||
|
_previewShown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool StickerPanInner::animStep(float64 ms) {
|
bool StickerPanInner::animStep(float64 ms) {
|
||||||
uint64 now = getms();
|
uint64 now = getms();
|
||||||
QRegion toUpdate;
|
QRegion toUpdate;
|
||||||
|
@ -1835,10 +1875,10 @@ _recent(this , qsl("emoji_group"), dbietRecent , QString(), true , st::r
|
||||||
_people(this , qsl("emoji_group"), dbietPeople , QString(), false, st::rbEmojiPeople),
|
_people(this , qsl("emoji_group"), dbietPeople , QString(), false, st::rbEmojiPeople),
|
||||||
_nature(this , qsl("emoji_group"), dbietNature , QString(), false, st::rbEmojiNature),
|
_nature(this , qsl("emoji_group"), dbietNature , QString(), false, st::rbEmojiNature),
|
||||||
_food(this , qsl("emoji_group"), dbietFood , QString(), false, st::rbEmojiFood),
|
_food(this , qsl("emoji_group"), dbietFood , QString(), false, st::rbEmojiFood),
|
||||||
_celebration(this, qsl("emoji_group"), dbietCelebration, QString(), false, st::rbEmojiCelebration),
|
_activity(this, qsl("emoji_group"), dbietActivity, QString(), false, st::rbEmojiActivity),
|
||||||
_activity(this , qsl("emoji_group"), dbietActivity , QString(), false, st::rbEmojiActivity),
|
|
||||||
_travel(this , qsl("emoji_group"), dbietTravel , QString(), false, st::rbEmojiTravel),
|
_travel(this , qsl("emoji_group"), dbietTravel , QString(), false, st::rbEmojiTravel),
|
||||||
_objects(this , qsl("emoji_group"), dbietObjects , QString(), false, st::rbEmojiObjects),
|
_objects(this , qsl("emoji_group"), dbietObjects , QString(), false, st::rbEmojiObjects),
|
||||||
|
_symbols(this , qsl("emoji_group"), dbietSymbols , QString(), false, st::rbEmojiSymbols),
|
||||||
_iconOver(-1), _iconSel(0), _iconDown(-1), _iconsDragging(false),
|
_iconOver(-1), _iconSel(0), _iconDown(-1), _iconsDragging(false),
|
||||||
_iconAnim(animFunc(this, &EmojiPan::iconAnim)),
|
_iconAnim(animFunc(this, &EmojiPan::iconAnim)),
|
||||||
_iconsLeft(0), _iconsTop(0), _iconsStartX(0), _iconsMax(0), _iconsX(0, 0), _iconSelX(0, 0), _iconsStartAnim(0),
|
_iconsLeft(0), _iconsTop(0), _iconsStartX(0), _iconsMax(0), _iconsX(0, 0), _iconSelX(0, 0), _iconsStartAnim(0),
|
||||||
|
@ -1872,10 +1912,10 @@ s_scroll(this, st::emojiScroll), s_inner(), s_switch(&s_scroll, false), _removin
|
||||||
prepareTab(left, top, _width, _people);
|
prepareTab(left, top, _width, _people);
|
||||||
prepareTab(left, top, _width, _nature);
|
prepareTab(left, top, _width, _nature);
|
||||||
prepareTab(left, top, _width, _food);
|
prepareTab(left, top, _width, _food);
|
||||||
prepareTab(left, top, _width, _celebration);
|
|
||||||
prepareTab(left, top, _width, _activity);
|
prepareTab(left, top, _width, _activity);
|
||||||
prepareTab(left, top, _width, _travel);
|
prepareTab(left, top, _width, _travel);
|
||||||
prepareTab(left, top, _width, _objects);
|
prepareTab(left, top, _width, _objects);
|
||||||
|
prepareTab(left, top, _width, _symbols);
|
||||||
e_inner.fillPanels(e_panels);
|
e_inner.fillPanels(e_panels);
|
||||||
updatePanelsPositions(e_panels, 0);
|
updatePanelsPositions(e_panels, 0);
|
||||||
|
|
||||||
|
@ -1903,7 +1943,7 @@ s_scroll(this, st::emojiScroll), s_inner(), s_switch(&s_scroll, false), _removin
|
||||||
connect(&e_inner, SIGNAL(needRefreshPanels()), this, SLOT(onRefreshPanels()));
|
connect(&e_inner, SIGNAL(needRefreshPanels()), this, SLOT(onRefreshPanels()));
|
||||||
connect(&s_inner, SIGNAL(needRefreshPanels()), this, SLOT(onRefreshPanels()));
|
connect(&s_inner, SIGNAL(needRefreshPanels()), this, SLOT(onRefreshPanels()));
|
||||||
|
|
||||||
if (cPlatform() == dbipMac) {
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1938,10 +1978,10 @@ void EmojiPan::setMaxHeight(int32 h) {
|
||||||
_people.move(_people.x(), _iconsTop);
|
_people.move(_people.x(), _iconsTop);
|
||||||
_nature.move(_nature.x(), _iconsTop);
|
_nature.move(_nature.x(), _iconsTop);
|
||||||
_food.move(_food.x(), _iconsTop);
|
_food.move(_food.x(), _iconsTop);
|
||||||
_celebration.move(_celebration.x(), _iconsTop);
|
|
||||||
_activity.move(_activity.x(), _iconsTop);
|
_activity.move(_activity.x(), _iconsTop);
|
||||||
_travel.move(_travel.x(), _iconsTop);
|
_travel.move(_travel.x(), _iconsTop);
|
||||||
_objects.move(_objects.x(), _iconsTop);
|
_objects.move(_objects.x(), _iconsTop);
|
||||||
|
_symbols.move(_symbols.x(), _iconsTop);
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -1976,6 +2016,8 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
|
||||||
p.fillRect(myrtlrect(r.x() + r.width() - st::emojiScroll.width, r.y(), st::emojiScroll.width, e_scroll.height()), st::white->b);
|
p.fillRect(myrtlrect(r.x() + r.width() - st::emojiScroll.width, r.y(), st::emojiScroll.width, e_scroll.height()), st::white->b);
|
||||||
if (_stickersShown) {
|
if (_stickersShown) {
|
||||||
p.fillRect(r.left(), _iconsTop, r.width(), st::rbEmoji.height, st::emojiPanCategories->b);
|
p.fillRect(r.left(), _iconsTop, r.width(), st::rbEmoji.height, st::emojiPanCategories->b);
|
||||||
|
p.drawSpriteLeft(_iconsLeft + 7 * st::rbEmoji.width + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), st::stickersSettings);
|
||||||
|
|
||||||
if (!_icons.isEmpty()) {
|
if (!_icons.isEmpty()) {
|
||||||
int32 x = _iconsLeft, i = 0, selxrel = _iconSelX.current(), selx = x + selxrel - _iconsX.current();
|
int32 x = _iconsLeft, i = 0, selxrel = _iconSelX.current(), selx = x + selxrel - _iconsX.current();
|
||||||
if (!_icons.at(i).sticker) {
|
if (!_icons.at(i).sticker) {
|
||||||
|
@ -1996,13 +2038,13 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect clip(x, _iconsTop, _iconsLeft + 8 * st::rbEmoji.width - x, st::rbEmoji.height);
|
QRect clip(x, _iconsTop, _iconsLeft + 7 * st::rbEmoji.width - x, st::rbEmoji.height);
|
||||||
if (rtl()) clip.moveLeft(width() - x - clip.width());
|
if (rtl()) clip.moveLeft(width() - x - clip.width());
|
||||||
p.setClipRect(clip);
|
p.setClipRect(clip);
|
||||||
|
|
||||||
i += _iconsX.current() / int(st::rbEmoji.width);
|
i += _iconsX.current() / int(st::rbEmoji.width);
|
||||||
x -= _iconsX.current() % int(st::rbEmoji.width);
|
x -= _iconsX.current() % int(st::rbEmoji.width);
|
||||||
for (int32 l = qMin(_icons.size(), i + 8 + (_icons.at(0).sticker ? 1 : 0)); i < l; ++i) {
|
for (int32 l = qMin(_icons.size(), i + 7 + (_icons.at(0).sticker ? 1 : 0)); i < l; ++i) {
|
||||||
const StickerIcon &s(_icons.at(i));
|
const StickerIcon &s(_icons.at(i));
|
||||||
s.sticker->thumb->load();
|
s.sticker->thumb->load();
|
||||||
QPixmap pix(s.sticker->thumb->pix(s.pixw, s.pixh));
|
QPixmap pix(s.sticker->thumb->pix(s.pixw, s.pixh));
|
||||||
|
@ -2028,7 +2070,7 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
|
||||||
float64 o_right = snap(float64(_iconsMax - _iconsX.current()) / st::stickerIconRight.pxWidth(), 0., 1.);
|
float64 o_right = snap(float64(_iconsMax - _iconsX.current()) / st::stickerIconRight.pxWidth(), 0., 1.);
|
||||||
if (o_right > 0) {
|
if (o_right > 0) {
|
||||||
p.setOpacity(o_right);
|
p.setOpacity(o_right);
|
||||||
p.drawSpriteRight(QRect(width() - _iconsLeft - 8 * st::rbEmoji.width, _iconsTop, st::stickerIconRight.pxWidth(), st::rbEmoji.height), width(), st::stickerIconRight);
|
p.drawSpriteRight(QRect(width() - _iconsLeft - 7 * st::rbEmoji.width, _iconsTop, st::stickerIconRight.pxWidth(), st::rbEmoji.height), width(), st::stickerIconRight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2100,27 +2142,31 @@ void EmojiPan::otherLeave() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::mousePressEvent(QMouseEvent *e) {
|
void EmojiPan::mousePressEvent(QMouseEvent *e) {
|
||||||
if (!_stickersShown || _icons.isEmpty()) return;
|
if (!_stickersShown) return;
|
||||||
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
|
if (_iconOver == _icons.size()) {
|
||||||
|
App::showLayer(new StickersBox());
|
||||||
|
} else {
|
||||||
_iconDown = _iconOver;
|
_iconDown = _iconOver;
|
||||||
_iconsMouseDown = _iconsMousePos;
|
_iconsMouseDown = _iconsMousePos;
|
||||||
_iconsStartX = _iconsX.current();
|
_iconsStartX = _iconsX.current();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::mouseMoveEvent(QMouseEvent *e) {
|
void EmojiPan::mouseMoveEvent(QMouseEvent *e) {
|
||||||
if (!_stickersShown || _icons.isEmpty()) return;
|
if (!_stickersShown) return;
|
||||||
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
if (!_iconsDragging && _iconDown >= (_icons.at(0).sticker ? 0 : 1)) {
|
if (!_iconsDragging && !_icons.isEmpty() && _iconDown >= (_icons.at(0).sticker ? 0 : 1)) {
|
||||||
if ((_iconsMousePos - _iconsMouseDown).manhattanLength() >= QApplication::startDragDistance()) {
|
if ((_iconsMousePos - _iconsMouseDown).manhattanLength() >= QApplication::startDragDistance()) {
|
||||||
_iconsDragging = true;
|
_iconsDragging = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_iconsDragging) {
|
if (_iconsDragging) {
|
||||||
int32 newX = snap(_iconsStartX + _iconsMouseDown.x() - _iconsMousePos.x(), 0, _iconsMax);
|
int32 newX = snap(_iconsStartX + (rtl() ? -1 : 1) * (_iconsMouseDown.x() - _iconsMousePos.x()), 0, _iconsMax);
|
||||||
if (newX != _iconsX.current()) {
|
if (newX != _iconsX.current()) {
|
||||||
_iconsX = anim::ivalue(newX, newX);
|
_iconsX = anim::ivalue(newX, newX);
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
|
@ -2150,7 +2196,7 @@ void EmojiPan::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
} else {
|
} else {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
if (wasDown == _iconOver && _iconOver >= 0) {
|
if (wasDown == _iconOver && _iconOver >= 0 && _iconOver < _icons.size()) {
|
||||||
_iconSelX = anim::ivalue(_iconOver * st::rbEmoji.width, _iconOver * st::rbEmoji.width);
|
_iconSelX = anim::ivalue(_iconOver * st::rbEmoji.width, _iconOver * st::rbEmoji.width);
|
||||||
s_inner.showStickerSet(_icons.at(_iconOver).setId);
|
s_inner.showStickerSet(_icons.at(_iconOver).setId);
|
||||||
}
|
}
|
||||||
|
@ -2160,7 +2206,7 @@ void EmojiPan::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
bool EmojiPan::event(QEvent *e) {
|
bool EmojiPan::event(QEvent *e) {
|
||||||
if (e->type() == QEvent::TouchBegin) {
|
if (e->type() == QEvent::TouchBegin) {
|
||||||
int a = 0;
|
int a = 0;
|
||||||
} else if (e->type() == QEvent::Wheel && _iconOver >= ((_icons.isEmpty() || _icons.at(0).sticker) ? 0 : 1) && _iconDown < 0) {
|
} else if (e->type() == QEvent::Wheel && !_icons.isEmpty() && _iconOver >= (_icons.at(0).sticker ? 0 : 1) && _iconOver < _icons.size() && _iconDown < 0) {
|
||||||
QWheelEvent *ev = static_cast<QWheelEvent*>(e);
|
QWheelEvent *ev = static_cast<QWheelEvent*>(e);
|
||||||
bool hor = (ev->angleDelta().x() != 0 || ev->orientation() == Qt::Horizontal);
|
bool hor = (ev->angleDelta().x() != 0 || ev->orientation() == Qt::Horizontal);
|
||||||
bool ver = (ev->angleDelta().y() != 0 || ev->orientation() == Qt::Vertical);
|
bool ver = (ev->angleDelta().y() != 0 || ev->orientation() == Qt::Vertical);
|
||||||
|
@ -2213,7 +2259,7 @@ void EmojiPan::onRefreshIcons() {
|
||||||
_iconsMax = 0;
|
_iconsMax = 0;
|
||||||
} else {
|
} else {
|
||||||
_iconHovers = QVector<float64>(_icons.size(), 0);
|
_iconHovers = QVector<float64>(_icons.size(), 0);
|
||||||
_iconsMax = qMax(int((_icons.size() - 8) * st::rbEmoji.width), 0);
|
_iconsMax = qMax(int((_icons.size() - 7) * st::rbEmoji.width), 0);
|
||||||
}
|
}
|
||||||
updatePanelsPositions(s_panels, s_scroll.scrollTop());
|
updatePanelsPositions(s_panels, s_scroll.scrollTop());
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
@ -2237,13 +2283,18 @@ void EmojiPan::leaveToChildEvent(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::updateSelected() {
|
void EmojiPan::updateSelected() {
|
||||||
if (_icons.isEmpty() || _iconDown >= 0) return;
|
if (_iconDown >= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QPoint p(mapFromGlobal(_iconsMousePos));
|
QPoint p(mapFromGlobal(_iconsMousePos));
|
||||||
int32 x = p.x(), y = p.y(), newOver = -1;
|
int32 x = p.x(), y = p.y(), newOver = -1;
|
||||||
if (rtl()) x = width() - x;
|
if (rtl()) x = width() - x;
|
||||||
x -= _iconsLeft;
|
x -= _iconsLeft;
|
||||||
if (y >= _iconsTop && y < _iconsTop + st::rbEmoji.height && x >= 0 && x < 8 * st::rbEmoji.width && x < _icons.size() * st::rbEmoji.width) {
|
if (x >= st::rbEmoji.width * 7 && x < st::rbEmoji.width * 8 && y >= _iconsTop && y < _iconsTop + st::rbEmoji.height) {
|
||||||
|
newOver = _icons.size();
|
||||||
|
} else if (!_icons.isEmpty()) {
|
||||||
|
if (y >= _iconsTop && y < _iconsTop + st::rbEmoji.height && x >= 0 && x < 7 * st::rbEmoji.width && x < _icons.size() * st::rbEmoji.width) {
|
||||||
if (!_icons.at(0).sticker) {
|
if (!_icons.at(0).sticker) {
|
||||||
if (x < st::rbEmoji.width) {
|
if (x < st::rbEmoji.width) {
|
||||||
newOver = 0;
|
newOver = 0;
|
||||||
|
@ -2256,6 +2307,7 @@ void EmojiPan::updateSelected() {
|
||||||
newOver = qFloor(x / st::rbEmoji.width) + (_icons.at(0).sticker ? 0 : 1);
|
newOver = qFloor(x / st::rbEmoji.width) + (_icons.at(0).sticker ? 0 : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (newOver != _iconOver) {
|
if (newOver != _iconOver) {
|
||||||
if (newOver < 0) {
|
if (newOver < 0) {
|
||||||
setCursor(style::cur_default);
|
setCursor(style::cur_default);
|
||||||
|
@ -2263,7 +2315,7 @@ void EmojiPan::updateSelected() {
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
bool startanim = false;
|
bool startanim = false;
|
||||||
if (_iconOver >= 0) {
|
if (_iconOver >= 0 && _iconOver < _icons.size()) {
|
||||||
_iconAnimations.remove(_iconOver + 1);
|
_iconAnimations.remove(_iconOver + 1);
|
||||||
if (_iconAnimations.find(-_iconOver - 1) == _iconAnimations.end()) {
|
if (_iconAnimations.find(-_iconOver - 1) == _iconAnimations.end()) {
|
||||||
if (_iconAnimations.isEmpty() && !_iconsStartAnim) startanim = true;
|
if (_iconAnimations.isEmpty() && !_iconsStartAnim) startanim = true;
|
||||||
|
@ -2271,7 +2323,7 @@ void EmojiPan::updateSelected() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_iconOver = newOver;
|
_iconOver = newOver;
|
||||||
if (_iconOver >= 0) {
|
if (_iconOver >= 0 && _iconOver < _icons.size()) {
|
||||||
_iconAnimations.remove(-_iconOver - 1);
|
_iconAnimations.remove(-_iconOver - 1);
|
||||||
if (_iconAnimations.find(_iconOver + 1) == _iconAnimations.end()) {
|
if (_iconAnimations.find(_iconOver + 1) == _iconAnimations.end()) {
|
||||||
if (_iconAnimations.isEmpty() && !_iconsStartAnim) startanim = true;
|
if (_iconAnimations.isEmpty() && !_iconsStartAnim) startanim = true;
|
||||||
|
@ -2474,10 +2526,10 @@ void EmojiPan::showAll() {
|
||||||
_people.hide();
|
_people.hide();
|
||||||
_nature.hide();
|
_nature.hide();
|
||||||
_food.hide();
|
_food.hide();
|
||||||
_celebration.hide();
|
|
||||||
_activity.hide();
|
_activity.hide();
|
||||||
_travel.hide();
|
_travel.hide();
|
||||||
_objects.hide();
|
_objects.hide();
|
||||||
|
_symbols.hide();
|
||||||
e_scroll.hide();
|
e_scroll.hide();
|
||||||
} else {
|
} else {
|
||||||
s_scroll.hide();
|
s_scroll.hide();
|
||||||
|
@ -2485,10 +2537,10 @@ void EmojiPan::showAll() {
|
||||||
_people.show();
|
_people.show();
|
||||||
_nature.show();
|
_nature.show();
|
||||||
_food.show();
|
_food.show();
|
||||||
_celebration.show();
|
|
||||||
_activity.show();
|
_activity.show();
|
||||||
_travel.show();
|
_travel.show();
|
||||||
_objects.show();
|
_objects.show();
|
||||||
|
_symbols.show();
|
||||||
e_scroll.show();
|
e_scroll.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2498,10 +2550,10 @@ void EmojiPan::hideAll() {
|
||||||
_people.hide();
|
_people.hide();
|
||||||
_nature.hide();
|
_nature.hide();
|
||||||
_food.hide();
|
_food.hide();
|
||||||
_celebration.hide();
|
|
||||||
_activity.hide();
|
_activity.hide();
|
||||||
_travel.hide();
|
_travel.hide();
|
||||||
_objects.hide();
|
_objects.hide();
|
||||||
|
_symbols.hide();
|
||||||
e_scroll.hide();
|
e_scroll.hide();
|
||||||
s_scroll.hide();
|
s_scroll.hide();
|
||||||
e_inner.clearSelection(true);
|
e_inner.clearSelection(true);
|
||||||
|
@ -2514,10 +2566,10 @@ void EmojiPan::onTabChange() {
|
||||||
if (_people.checked()) newTab = dbietPeople;
|
if (_people.checked()) newTab = dbietPeople;
|
||||||
else if (_nature.checked()) newTab = dbietNature;
|
else if (_nature.checked()) newTab = dbietNature;
|
||||||
else if (_food.checked()) newTab = dbietFood;
|
else if (_food.checked()) newTab = dbietFood;
|
||||||
else if (_celebration.checked()) newTab = dbietCelebration;
|
|
||||||
else if (_activity.checked()) newTab = dbietActivity;
|
else if (_activity.checked()) newTab = dbietActivity;
|
||||||
else if (_travel.checked()) newTab = dbietTravel;
|
else if (_travel.checked()) newTab = dbietTravel;
|
||||||
else if (_objects.checked()) newTab = dbietObjects;
|
else if (_objects.checked()) newTab = dbietObjects;
|
||||||
|
else if (_symbols.checked()) newTab = dbietSymbols;
|
||||||
e_inner.showEmojiPack(newTab);
|
e_inner.showEmojiPack(newTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2544,10 +2596,10 @@ void EmojiPan::onScroll() {
|
||||||
case dbietPeople : check = &_people ; break;
|
case dbietPeople : check = &_people ; break;
|
||||||
case dbietNature : check = &_nature ; break;
|
case dbietNature : check = &_nature ; break;
|
||||||
case dbietFood : check = &_food ; break;
|
case dbietFood : check = &_food ; break;
|
||||||
case dbietCelebration: check = &_celebration; break;
|
case dbietActivity: check = &_activity; break;
|
||||||
case dbietActivity : check = &_activity ; break;
|
|
||||||
case dbietTravel : check = &_travel ; break;
|
case dbietTravel : check = &_travel ; break;
|
||||||
case dbietObjects : check = &_objects ; break;
|
case dbietObjects : check = &_objects ; break;
|
||||||
|
case dbietSymbols : check = &_symbols ; break;
|
||||||
}
|
}
|
||||||
if (check && !check->checked()) {
|
if (check && !check->checked()) {
|
||||||
_noTabUpdate = true;
|
_noTabUpdate = true;
|
||||||
|
@ -2644,8 +2696,9 @@ void EmojiPan::onRemoveSetSure() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cRefStickerSets().erase(it);
|
cRefStickerSets().erase(it);
|
||||||
cRefStickerSetsOrder().removeOne(_removingSetId);
|
int32 removeIndex = cStickerSetsOrder().indexOf(_removingSetId);
|
||||||
cSetStickersHash(QByteArray());
|
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
|
||||||
|
cSetStickersHash(stickersCountHash());
|
||||||
refreshStickers();
|
refreshStickers();
|
||||||
Local::writeStickers();
|
Local::writeStickers();
|
||||||
if (writeRecent) Local::writeUserSettings();
|
if (writeRecent) Local::writeUserSettings();
|
||||||
|
@ -2920,6 +2973,8 @@ _scroll(this, st::mentionScroll), _inner(this, &_rows, &_hrows, &_crows), _chat(
|
||||||
connect(&_inner, SIGNAL(chosen(QString)), this, SIGNAL(chosen(QString)));
|
connect(&_inner, SIGNAL(chosen(QString)), this, SIGNAL(chosen(QString)));
|
||||||
connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int)));
|
connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int)));
|
||||||
|
|
||||||
|
connect(App::wnd(), SIGNAL(imageLoaded()), &_inner, SLOT(update()));
|
||||||
|
|
||||||
setFocusPolicy(Qt::NoFocus);
|
setFocusPolicy(Qt::NoFocus);
|
||||||
_scroll.setFocusPolicy(Qt::NoFocus);
|
_scroll.setFocusPolicy(Qt::NoFocus);
|
||||||
_scroll.viewport()->setFocusPolicy(Qt::NoFocus);
|
_scroll.viewport()->setFocusPolicy(Qt::NoFocus);
|
||||||
|
@ -2934,7 +2989,7 @@ _scroll(this, st::mentionScroll), _inner(this, &_rows, &_hrows, &_crows), _chat(
|
||||||
connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged()));
|
connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged()));
|
||||||
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(onUpdateSelected()));
|
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(onUpdateSelected()));
|
||||||
|
|
||||||
if (cPlatform() == dbipMac) {
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,6 +348,8 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void updateSelected();
|
void updateSelected();
|
||||||
|
void onSettings();
|
||||||
|
void onPreview();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
@ -391,6 +393,11 @@ private:
|
||||||
|
|
||||||
int32 _selected, _pressedSel;
|
int32 _selected, _pressedSel;
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
|
|
||||||
|
LinkButton _settings;
|
||||||
|
|
||||||
|
QTimer _previewTimer;
|
||||||
|
bool _previewShown;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmojiPanel : public TWidget {
|
class EmojiPanel : public TWidget {
|
||||||
|
@ -545,7 +552,7 @@ private:
|
||||||
|
|
||||||
BoxShadow _shadow;
|
BoxShadow _shadow;
|
||||||
|
|
||||||
FlatRadiobutton _recent, _people, _nature, _food, _celebration, _activity, _travel, _objects;
|
FlatRadiobutton _recent, _people, _nature, _food, _activity, _travel, _objects, _symbols;
|
||||||
QVector<StickerIcon> _icons;
|
QVector<StickerIcon> _icons;
|
||||||
QVector<float64> _iconHovers;
|
QVector<float64> _iconHovers;
|
||||||
int32 _iconOver, _iconSel, _iconDown;
|
int32 _iconOver, _iconSel, _iconDown;
|
||||||
|
|
109
Telegram/SourceFiles/facades.cpp
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop 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.
|
||||||
|
|
||||||
|
It 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.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
#include "mainwidget.h"
|
||||||
|
|
||||||
|
namespace App {
|
||||||
|
|
||||||
|
void sendBotCommand(const QString &cmd, MsgId replyTo) {
|
||||||
|
if (MainWidget *m = main()) m->sendBotCommand(cmd, replyTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertBotCommand(const QString &cmd) {
|
||||||
|
if (MainWidget *m = main()) m->insertBotCommand(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
||||||
|
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openPeerByName(const QString &username, bool toProfile, const QString &startToken) {
|
||||||
|
if (MainWidget *m = main()) m->openPeerByName(username, toProfile, startToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void joinGroupByHash(const QString &hash) {
|
||||||
|
if (MainWidget *m = main()) m->joinGroupByHash(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stickersBox(const QString &name) {
|
||||||
|
if (MainWidget *m = main()) m->stickersBox(MTP_inputStickerSetShortName(MTP_string(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void openLocalUrl(const QString &url) {
|
||||||
|
if (MainWidget *m = main()) m->openLocalUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool forward(const PeerId &peer, ForwardWhatMessages what) {
|
||||||
|
if (MainWidget *m = main()) return m->onForward(peer, what);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeDialog(History *history) {
|
||||||
|
if (MainWidget *m = main()) m->removeDialog(history);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showSettings() {
|
||||||
|
if (Window *win = wnd()) win->showSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showLayer(LayeredWidget *widget, bool forceFast) {
|
||||||
|
if (Window *w = wnd()) w->showLayer(widget, forceFast);
|
||||||
|
}
|
||||||
|
|
||||||
|
void replaceLayer(LayeredWidget *widget) {
|
||||||
|
if (Window *w = wnd()) w->replaceLayer(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showLayerLast(LayeredWidget *widget) {
|
||||||
|
if (Window *w = wnd()) w->showLayerLast(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
void showStickerPreview(DocumentData *sticker) {
|
||||||
|
if (MainWidget *m = App::main()) m->ui_showStickerPreview(sticker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hideStickerPreview() {
|
||||||
|
if (MainWidget *m = App::main()) m->ui_hideStickerPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Notify {
|
||||||
|
|
||||||
|
void userIsBotChanged(UserData *user) {
|
||||||
|
if (MainWidget *m = App::main()) m->notifyUserIsBotChanged(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
void botCommandsChanged(UserData *user) {
|
||||||
|
if (MainWidget *m = App::main()) m->notifyBotCommandsChanged(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
void migrateUpdated(PeerData *peer) {
|
||||||
|
if (MainWidget *m = App::main()) m->notifyMigrateUpdated(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
Telegram/SourceFiles/facades.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop 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.
|
||||||
|
|
||||||
|
It 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.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class LayeredWidget;
|
||||||
|
|
||||||
|
namespace App {
|
||||||
|
|
||||||
|
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
||||||
|
void insertBotCommand(const QString &cmd);
|
||||||
|
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
||||||
|
void openPeerByName(const QString &username, bool toProfile = false, const QString &startToken = QString());
|
||||||
|
void joinGroupByHash(const QString &hash);
|
||||||
|
void stickersBox(const QString &name);
|
||||||
|
void openLocalUrl(const QString &url);
|
||||||
|
bool forward(const PeerId &peer, ForwardWhatMessages what);
|
||||||
|
void removeDialog(History *history);
|
||||||
|
void showSettings();
|
||||||
|
void showLayer(LayeredWidget *w, bool forceFast = false);
|
||||||
|
void replaceLayer(LayeredWidget *w);
|
||||||
|
void showLayerLast(LayeredWidget *w);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Ui { // it doesn't allow me to use UI :(
|
||||||
|
|
||||||
|
void showStickerPreview(DocumentData *sticker);
|
||||||
|
void hideStickerPreview();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Notify {
|
||||||
|
|
||||||
|
void userIsBotChanged(UserData *user);
|
||||||
|
void botCommandsChanged(UserData *user);
|
||||||
|
void migrateUpdated(PeerData *peer);
|
||||||
|
|
||||||
|
};
|
|
@ -41,7 +41,7 @@ void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &me
|
||||||
}
|
}
|
||||||
document->status = FileUploading;
|
document->status = FileUploading;
|
||||||
if (!media.file.isEmpty()) {
|
if (!media.file.isEmpty()) {
|
||||||
document->location = FileLocation(StorageFilePartial, media.file);
|
document->setLocation(FileLocation(StorageFilePartial, media.file));
|
||||||
}
|
}
|
||||||
} else if (media.type == PrepareAudio) {
|
} else if (media.type == PrepareAudio) {
|
||||||
AudioData *audio = App::feedAudio(media.audio);
|
AudioData *audio = App::feedAudio(media.audio);
|
||||||
|
@ -64,7 +64,7 @@ void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file)
|
||||||
}
|
}
|
||||||
document->status = FileUploading;
|
document->status = FileUploading;
|
||||||
if (!file->filepath.isEmpty()) {
|
if (!file->filepath.isEmpty()) {
|
||||||
document->location = FileLocation(StorageFilePartial, file->filepath);
|
document->setLocation(FileLocation(StorageFilePartial, file->filepath));
|
||||||
}
|
}
|
||||||
} else if (file->type == PrepareAudio) {
|
} else if (file->type == PrepareAudio) {
|
||||||
AudioData *audio = App::feedAudio(file->audio);
|
AudioData *audio = App::feedAudio(file->audio);
|
||||||
|
|
|
@ -161,10 +161,17 @@ bool AnimatedGif::animStep(float64 ms) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimatedGif::start(HistoryItem *row, const QString &file) {
|
void AnimatedGif::start(HistoryItem *row, const FileLocation &f) {
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
reader = new QImageReader(file);
|
file = new FileLocation(f);
|
||||||
|
if (!file->accessEnable()) {
|
||||||
|
stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
access = true;
|
||||||
|
|
||||||
|
reader = new QImageReader(file->name());
|
||||||
if (!reader->canRead() || !reader->supportsAnimation()) {
|
if (!reader->canRead() || !reader->supportsAnimation()) {
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
|
@ -206,6 +213,15 @@ void AnimatedGif::start(HistoryItem *row, const QString &file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimatedGif::stop(bool onItemRemoved) {
|
void AnimatedGif::stop(bool onItemRemoved) {
|
||||||
|
if (file) {
|
||||||
|
if (access) {
|
||||||
|
file->accessDisable();
|
||||||
|
}
|
||||||
|
delete file;
|
||||||
|
file = 0;
|
||||||
|
}
|
||||||
|
access = false;
|
||||||
|
|
||||||
if (isNull()) return;
|
if (isNull()) return;
|
||||||
|
|
||||||
delete reader;
|
delete reader;
|
||||||
|
|
|
@ -387,17 +387,18 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
|
class FileLocation;
|
||||||
class AnimatedGif : public QObject, public Animated {
|
class AnimatedGif : public QObject, public Animated {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AnimatedGif() : msg(0), reader(0), w(0), h(0), frame(0), framesCount(0), duration(0) {
|
AnimatedGif() : msg(0), file(0), access(false), reader(0), w(0), h(0), frame(0), framesCount(0), duration(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool animStep(float64 ms);
|
bool animStep(float64 ms);
|
||||||
|
|
||||||
void start(HistoryItem *row, const QString &file);
|
void start(HistoryItem *row, const FileLocation &file);
|
||||||
void stop(bool onItemRemoved = false);
|
void stop(bool onItemRemoved = false);
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
|
@ -418,6 +419,8 @@ public:
|
||||||
|
|
||||||
HistoryItem *msg;
|
HistoryItem *msg;
|
||||||
QImage img;
|
QImage img;
|
||||||
|
FileLocation *file;
|
||||||
|
bool access;
|
||||||
QImageReader *reader;
|
QImageReader *reader;
|
||||||
int32 w, h, frame;
|
int32 w, h, frame;
|
||||||
|
|
||||||
|
|
|
@ -151,98 +151,3 @@ private:
|
||||||
|
|
||||||
ScrollableBoxShadow _topShadow;
|
ScrollableBoxShadow _topShadow;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** /
|
|
||||||
class CountryList : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
CountryList(QWidget *parent, const style::countryList &st = st::countryList);
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
|
||||||
void mouseMoveEvent(QMouseEvent *e);
|
|
||||||
void mousePressEvent(QMouseEvent *e);
|
|
||||||
void enterEvent(QEvent *e);
|
|
||||||
void leaveEvent(QEvent *e);
|
|
||||||
|
|
||||||
void selectSkip(int delta);
|
|
||||||
void selectSkipPage(int h, int delta);
|
|
||||||
|
|
||||||
void updateFiltered();
|
|
||||||
|
|
||||||
QString getSelectedCountry() const;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
void onUpdateSelected(bool force = false);
|
|
||||||
void onParentGeometryChanged();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
void countrySelected();
|
|
||||||
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void resetList();
|
|
||||||
void setSelected(int newSelected);
|
|
||||||
|
|
||||||
int _sel;
|
|
||||||
style::countryList _st;
|
|
||||||
QPoint _mousePos;
|
|
||||||
|
|
||||||
bool _mouseSel;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class CountrySelect : public QWidget, public Animated {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
CountrySelect();
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
|
||||||
void keyPressEvent(QKeyEvent *e);
|
|
||||||
void mousePressEvent(QMouseEvent *e);
|
|
||||||
void resizeEvent(QResizeEvent *e);
|
|
||||||
|
|
||||||
bool animStep(float64 ms);
|
|
||||||
|
|
||||||
~CountrySelect();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
void countryChosen(const QString &country = QString());
|
|
||||||
void countryFinished();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
void onParentResize(const QSize &newSize);
|
|
||||||
void onCountryChoose();
|
|
||||||
void onCountryCancel();
|
|
||||||
void onScrollFinished();
|
|
||||||
void onFilterUpdate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void finish(const QString &res);
|
|
||||||
void prepareAnimation(int to);
|
|
||||||
|
|
||||||
QString _result;
|
|
||||||
FlatInput _filter;
|
|
||||||
ScrollArea _scroll;
|
|
||||||
CountryList _list;
|
|
||||||
BoxButton _doneButton, _cancelButton;
|
|
||||||
int32 _innerLeft, _innerTop, _innerWidth, _innerHeight;
|
|
||||||
|
|
||||||
anim::fvalue a_alpha, a_bgAlpha;
|
|
||||||
anim::ivalue a_coord;
|
|
||||||
anim::transition af_alpha, af_bgAlpha, af_coord;
|
|
||||||
QPixmap _cache;
|
|
||||||
|
|
||||||
BoxShadow _shadow;
|
|
||||||
|
|
||||||
};
|
|
||||||
*/
|
|
|
@ -85,7 +85,7 @@ inline EmojiPtr emojiFromUrl(const QString &url) {
|
||||||
|
|
||||||
inline EmojiPtr emojiFromText(const QChar *ch, const QChar *e, int &len) {
|
inline EmojiPtr emojiFromText(const QChar *ch, const QChar *e, int &len) {
|
||||||
EmojiPtr emoji = 0;
|
EmojiPtr emoji = 0;
|
||||||
if (ch + 1 < e && ((ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) || (((ch->unicode() >= 48 && ch->unicode() < 58) || ch->unicode() == 35) && (ch + 1)->unicode() == 0x20E3))) {
|
if (ch + 1 < e && ((ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) || (((ch->unicode() >= 0x30 && ch->unicode() < 0x3A) || ch->unicode() == 0x23 || ch->unicode() == 0x2A) && (ch + 1)->unicode() == 0x20E3))) {
|
||||||
uint32 code = (ch->unicode() << 16) | (ch + 1)->unicode();
|
uint32 code = (ch->unicode() << 16) | (ch + 1)->unicode();
|
||||||
emoji = emojiGet(code);
|
emoji = emojiGet(code);
|
||||||
if (emoji) {
|
if (emoji) {
|
||||||
|
@ -105,6 +105,11 @@ inline EmojiPtr emojiFromText(const QChar *ch, const QChar *e, int &len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (ch + 2 < e && ((ch->unicode() >= 0x30 && ch->unicode() < 0x3A) || ch->unicode() == 0x23 || ch->unicode() == 0x2A) && (ch + 1)->unicode() == 0xFE0F && (ch + 2)->unicode() == 0x20E3) {
|
||||||
|
uint32 code = (ch->unicode() << 16) | (ch + 2)->unicode();
|
||||||
|
emoji = emojiGet(code);
|
||||||
|
len = emoji->len + 1;
|
||||||
|
return emoji;
|
||||||
} else if (ch < e) {
|
} else if (ch < e) {
|
||||||
emoji = emojiGet(ch->unicode());
|
emoji = emojiGet(ch->unicode());
|
||||||
Q_ASSERT(emoji != TwoSymbolEmoji);
|
Q_ASSERT(emoji != TwoSymbolEmoji);
|
||||||
|
|
|
@ -89,7 +89,7 @@ bool _filedialogGetFiles(QStringList &files, QByteArray &remoteContent, const QS
|
||||||
}
|
}
|
||||||
return !files.isEmpty();
|
return !files.isEmpty();
|
||||||
} else if (multipleFiles < -1) {
|
} else if (multipleFiles < -1) {
|
||||||
file = QFileDialog::getExistingDirectory(App::wnd() ? App::wnd()->filedialogParent() : 0, caption);
|
file = QFileDialog::getExistingDirectory(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile);
|
||||||
} else if (multipleFiles < 0) {
|
} else if (multipleFiles < 0) {
|
||||||
file = QFileDialog::getSaveFileName(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter);
|
file = QFileDialog::getSaveFileName(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1180,7 +1180,7 @@ void InputArea::setCtrlEnterSubmit(CtrlEnterSubmit ctrlEnterSubmit) {
|
||||||
|
|
||||||
void InputArea::InputAreaInner::keyPressEvent(QKeyEvent *e) {
|
void InputArea::InputAreaInner::keyPressEvent(QKeyEvent *e) {
|
||||||
bool shift = e->modifiers().testFlag(Qt::ShiftModifier), alt = e->modifiers().testFlag(Qt::AltModifier);
|
bool shift = e->modifiers().testFlag(Qt::ShiftModifier), alt = e->modifiers().testFlag(Qt::AltModifier);
|
||||||
bool macmeta = (cPlatform() == dbipMac) && e->modifiers().testFlag(Qt::ControlModifier) && !e->modifiers().testFlag(Qt::MetaModifier) && !e->modifiers().testFlag(Qt::AltModifier);
|
bool macmeta = (cPlatform() == dbipMac || cPlatform() == dbipMacOld) && e->modifiers().testFlag(Qt::ControlModifier) && !e->modifiers().testFlag(Qt::MetaModifier) && !e->modifiers().testFlag(Qt::AltModifier);
|
||||||
bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier);
|
bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier);
|
||||||
bool ctrlGood = (ctrl && shift) ||
|
bool ctrlGood = (ctrl && shift) ||
|
||||||
(ctrl && (f()->_ctrlEnterSubmit == CtrlEnterSubmitCtrlEnter || f()->_ctrlEnterSubmit == CtrlEnterSubmitBoth)) ||
|
(ctrl && (f()->_ctrlEnterSubmit == CtrlEnterSubmitCtrlEnter || f()->_ctrlEnterSubmit == CtrlEnterSubmitBoth)) ||
|
||||||
|
@ -1904,7 +1904,7 @@ void InputField::customUpDown(bool custom) {
|
||||||
|
|
||||||
void InputField::InputFieldInner::keyPressEvent(QKeyEvent *e) {
|
void InputField::InputFieldInner::keyPressEvent(QKeyEvent *e) {
|
||||||
bool shift = e->modifiers().testFlag(Qt::ShiftModifier), alt = e->modifiers().testFlag(Qt::AltModifier);
|
bool shift = e->modifiers().testFlag(Qt::ShiftModifier), alt = e->modifiers().testFlag(Qt::AltModifier);
|
||||||
bool macmeta = (cPlatform() == dbipMac) && e->modifiers().testFlag(Qt::ControlModifier) && !e->modifiers().testFlag(Qt::MetaModifier) && !e->modifiers().testFlag(Qt::AltModifier);
|
bool macmeta = (cPlatform() == dbipMac || cPlatform() == dbipMacOld) && e->modifiers().testFlag(Qt::ControlModifier) && !e->modifiers().testFlag(Qt::MetaModifier) && !e->modifiers().testFlag(Qt::AltModifier);
|
||||||
bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier), ctrlGood = true;
|
bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier), ctrlGood = true;
|
||||||
bool enter = (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return);
|
bool enter = (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return);
|
||||||
|
|
||||||
|
|
|
@ -860,7 +860,7 @@ void FlatTextarea::setCtrlEnterSubmit(bool ctrlEnterSubmit) {
|
||||||
|
|
||||||
void FlatTextarea::keyPressEvent(QKeyEvent *e) {
|
void FlatTextarea::keyPressEvent(QKeyEvent *e) {
|
||||||
bool shift = e->modifiers().testFlag(Qt::ShiftModifier);
|
bool shift = e->modifiers().testFlag(Qt::ShiftModifier);
|
||||||
bool macmeta = (cPlatform() == dbipMac) && e->modifiers().testFlag(Qt::ControlModifier) && !e->modifiers().testFlag(Qt::MetaModifier) && !e->modifiers().testFlag(Qt::AltModifier);
|
bool macmeta = (cPlatform() == dbipMac || cPlatform() == dbipMacOld) && e->modifiers().testFlag(Qt::ControlModifier) && !e->modifiers().testFlag(Qt::MetaModifier) && !e->modifiers().testFlag(Qt::AltModifier);
|
||||||
bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier), ctrlGood = (ctrl && _ctrlEnterSubmit) || (!ctrl && !shift && !_ctrlEnterSubmit) || (ctrl && shift);
|
bool ctrl = e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier), ctrlGood = (ctrl && _ctrlEnterSubmit) || (!ctrl && !shift && !_ctrlEnterSubmit) || (ctrl && shift);
|
||||||
bool enter = (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return);
|
bool enter = (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
|
#include "pspecific.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
typedef QMap<QString, LocalImage*> LocalImages;
|
typedef QMap<QString, LocalImage*> LocalImages;
|
||||||
LocalImages localImages;
|
LocalImages localImages;
|
||||||
|
@ -712,3 +714,82 @@ StorageImage *getImage(const StorageImageLocation &location, const QByteArray &b
|
||||||
}
|
}
|
||||||
return i.value();
|
return i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReadAccessEnabler::ReadAccessEnabler(const PsFileBookmark *bookmark) : _bookmark(bookmark), _failed(_bookmark ? !_bookmark->enable() : false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadAccessEnabler::ReadAccessEnabler(const QSharedPointer<PsFileBookmark> &bookmark) : _bookmark(bookmark.data()), _failed(_bookmark ? !_bookmark->enable() : false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadAccessEnabler::~ReadAccessEnabler() {
|
||||||
|
if (_bookmark && !_failed) _bookmark->disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileLocation::FileLocation(StorageFileType type, const QString &name) : type(type), fname(name) {
|
||||||
|
if (fname.isEmpty()) {
|
||||||
|
size = 0;
|
||||||
|
type = StorageFileUnknown;
|
||||||
|
} else {
|
||||||
|
setBookmark(psPathBookmark(name));
|
||||||
|
|
||||||
|
QFileInfo f(name);
|
||||||
|
if (f.exists()) {
|
||||||
|
qint64 s = f.size();
|
||||||
|
if (s > INT_MAX) {
|
||||||
|
fname = QString();
|
||||||
|
_bookmark.reset(0);
|
||||||
|
size = 0;
|
||||||
|
type = StorageFileUnknown;
|
||||||
|
} else {
|
||||||
|
modified = f.lastModified();
|
||||||
|
size = qint32(s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fname = QString();
|
||||||
|
_bookmark.reset(0);
|
||||||
|
size = 0;
|
||||||
|
type = StorageFileUnknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileLocation::check() const {
|
||||||
|
if (fname.isEmpty()) return false;
|
||||||
|
|
||||||
|
ReadAccessEnabler enabler(_bookmark);
|
||||||
|
if (enabler.failed()) {
|
||||||
|
const_cast<FileLocation*>(this)->_bookmark.reset(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo f(name());
|
||||||
|
if (!f.isReadable()) return false;
|
||||||
|
|
||||||
|
quint64 s = f.size();
|
||||||
|
if (s > INT_MAX) return false;
|
||||||
|
|
||||||
|
return (f.lastModified() == modified) && (qint32(s) == size);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &FileLocation::name() const {
|
||||||
|
return _bookmark ? _bookmark->name(fname) : fname;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FileLocation::bookmark() const {
|
||||||
|
return _bookmark ? _bookmark->bookmark() : QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileLocation::setBookmark(const QByteArray &bm) {
|
||||||
|
if (bm.isEmpty()) {
|
||||||
|
_bookmark.reset(0);
|
||||||
|
} else {
|
||||||
|
_bookmark.reset(new PsFileBookmark(bm));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileLocation::accessEnable() const {
|
||||||
|
return isEmpty() ? false : (_bookmark ? _bookmark->enable() : true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileLocation::accessDisable() const {
|
||||||
|
return _bookmark ? _bookmark->disable() : (void)0;
|
||||||
|
}
|
||||||
|
|
|
@ -240,46 +240,50 @@ void clearStorageImages();
|
||||||
void clearAllImages();
|
void clearAllImages();
|
||||||
int64 imageCacheSize();
|
int64 imageCacheSize();
|
||||||
|
|
||||||
struct FileLocation {
|
class PsFileBookmark;
|
||||||
FileLocation(StorageFileType type, const QString &name, const QDateTime &modified, qint32 size) : type(type), name(name), modified(modified), size(size) {
|
class ReadAccessEnabler {
|
||||||
}
|
public:
|
||||||
FileLocation(StorageFileType type, const QString &name) : type(type), name(name) {
|
ReadAccessEnabler(const PsFileBookmark *bookmark);
|
||||||
QFileInfo f(name);
|
ReadAccessEnabler(const QSharedPointer<PsFileBookmark> &bookmark);
|
||||||
if (f.exists()) {
|
bool failed() const {
|
||||||
qint64 s = f.size();
|
return _failed;
|
||||||
if (s > INT_MAX) {
|
|
||||||
this->name = QString();
|
|
||||||
size = 0;
|
|
||||||
type = StorageFileUnknown;
|
|
||||||
} else {
|
|
||||||
modified = f.lastModified();
|
|
||||||
size = qint32(s);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this->name = QString();
|
|
||||||
size = 0;
|
|
||||||
type = StorageFileUnknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
~ReadAccessEnabler();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const PsFileBookmark *_bookmark;
|
||||||
|
bool _failed;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileLocation {
|
||||||
|
public:
|
||||||
|
FileLocation(StorageFileType type, const QString &name);
|
||||||
FileLocation() : size(0) {
|
FileLocation() : size(0) {
|
||||||
}
|
}
|
||||||
bool check() const {
|
|
||||||
if (name.isEmpty()) return false;
|
|
||||||
QFileInfo f(name);
|
|
||||||
if (!f.exists()) return false;
|
|
||||||
|
|
||||||
quint64 s = f.size();
|
bool check() const;
|
||||||
if (s > INT_MAX) return false;
|
const QString &name() const;
|
||||||
|
void setBookmark(const QByteArray &bookmark);
|
||||||
return (f.lastModified() == modified) && (qint32(s) == size);
|
QByteArray bookmark() const;
|
||||||
|
bool isEmpty() const {
|
||||||
|
return name().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool accessEnable() const;
|
||||||
|
void accessDisable() const;
|
||||||
|
|
||||||
StorageFileType type;
|
StorageFileType type;
|
||||||
QString name;
|
QString fname;
|
||||||
QDateTime modified;
|
QDateTime modified;
|
||||||
qint32 size;
|
qint32 size;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<PsFileBookmark> _bookmark;
|
||||||
|
|
||||||
};
|
};
|
||||||
inline bool operator==(const FileLocation &a, const FileLocation &b) {
|
inline bool operator==(const FileLocation &a, const FileLocation &b) {
|
||||||
return a.type == b.type && a.name == b.name && a.modified == b.modified && a.size == b.size;
|
return a.type == b.type && a.name() == b.name() && a.modified == b.modified && a.size == b.size;
|
||||||
}
|
}
|
||||||
inline bool operator!=(const FileLocation &a, const FileLocation &b) {
|
inline bool operator!=(const FileLocation &a, const FileLocation &b) {
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
|
|
|
@ -545,7 +545,7 @@ public:
|
||||||
void parseCurrentChar() {
|
void parseCurrentChar() {
|
||||||
int skipBack = 0;
|
int skipBack = 0;
|
||||||
ch = ((ptr < end) ? *ptr : 0);
|
ch = ((ptr < end) ? *ptr : 0);
|
||||||
chInt = ch.unicode();
|
emojiLookback = 0;
|
||||||
bool skip = false, isNewLine = multiline && chIsNewline(ch), isSpace = chIsSpace(ch), isDiac = chIsDiac(ch), isTilde = checkTilde && (ch == '~');
|
bool skip = false, isNewLine = multiline && chIsNewline(ch), isSpace = chIsSpace(ch), isDiac = chIsDiac(ch), isTilde = checkTilde && (ch == '~');
|
||||||
if (chIsBad(ch) || ch.isLowSurrogate()) {
|
if (chIsBad(ch) || ch.isLowSurrogate()) {
|
||||||
skip = true;
|
skip = true;
|
||||||
|
@ -561,15 +561,7 @@ public:
|
||||||
skipBack = -1;
|
skipBack = -1;
|
||||||
++ptr;
|
++ptr;
|
||||||
ch = *ptr;
|
ch = *ptr;
|
||||||
chInt = (chInt << 16) | ch.unicode();
|
emojiLookback = 1;
|
||||||
}
|
|
||||||
} else if ((ch >= 48 && ch < 58) || ch == 35) { // check for digit emoji
|
|
||||||
if (ptr + 1 < end && (ptr + 1)->unicode() == 0x20E3) {
|
|
||||||
_t->_text.push_back(ch);
|
|
||||||
skipBack = -1;
|
|
||||||
++ptr;
|
|
||||||
ch = *ptr;
|
|
||||||
chInt = (chInt << 16) | 0x20E3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,11 +593,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseEmojiFromCurrent() {
|
void parseEmojiFromCurrent() {
|
||||||
int len = 0, skipped = (chInt > 0xFFFFU) ? 1 : 0;
|
int len = 0;
|
||||||
EmojiPtr e = emojiFromText(ptr - skipped, end, len);
|
EmojiPtr e = emojiFromText(ptr - emojiLookback, end, len);
|
||||||
if (!e) return;
|
if (!e) return;
|
||||||
|
|
||||||
for (int l = len - skipped - 1; l > 0; --l) {
|
for (int l = len - emojiLookback - 1; l > 0; --l) {
|
||||||
_t->_text.push_back(*++ptr);
|
_t->_text.push_back(*++ptr);
|
||||||
}
|
}
|
||||||
if (e->postfix && _t->_text.at(_t->_text.size() - 1).unicode() != e->postfix) {
|
if (e->postfix && _t->_text.at(_t->_text.size() - 1).unicode() != e->postfix) {
|
||||||
|
@ -688,7 +680,7 @@ public:
|
||||||
blockStart = 0;
|
blockStart = 0;
|
||||||
emoji = 0;
|
emoji = 0;
|
||||||
|
|
||||||
ch = chInt = 0;
|
ch = emojiLookback = 0;
|
||||||
lastSkipped = false;
|
lastSkipped = false;
|
||||||
checkTilde = !cRetina() && _t->_font->size() == 13 && _t->_font->flags() == 0; // tilde Open Sans fix
|
checkTilde = !cRetina() && _t->_font->size() == 13 && _t->_font->flags() == 0; // tilde Open Sans fix
|
||||||
entitiesEnd = entities.cend();
|
entitiesEnd = entities.cend();
|
||||||
|
@ -789,7 +781,7 @@ private:
|
||||||
|
|
||||||
// current char data
|
// current char data
|
||||||
QChar ch; // current char (low surrogate, if current char is surrogate pair)
|
QChar ch; // current char (low surrogate, if current char is surrogate pair)
|
||||||
uint32 chInt; // full ch, could be surrogate pair
|
int32 emojiLookback; // how far behind the current ptr to look for current emoji
|
||||||
bool lastSkipped; // did we skip current char
|
bool lastSkipped; // did we skip current char
|
||||||
bool checkTilde; // do we need a special text block for tilde symbol
|
bool checkTilde; // do we need a special text block for tilde symbol
|
||||||
};
|
};
|
||||||
|
@ -1112,8 +1104,8 @@ public:
|
||||||
|
|
||||||
if (_btype == TextBlockTText) {
|
if (_btype == TextBlockTText) {
|
||||||
TextBlock *t = static_cast<TextBlock*>(b);
|
TextBlock *t = static_cast<TextBlock*>(b);
|
||||||
QFixed f_wLeft = _wLeft;
|
QFixed f_wLeft = _wLeft; // vars for saving state of the last word start
|
||||||
int32 f_lineHeight = _lineHeight;
|
int32 f_lineHeight = _lineHeight; // f points to the last word-start element of t->_words
|
||||||
for (TextBlock::TextWords::const_iterator j = t->_words.cbegin(), en = t->_words.cend(), f = j; j != en; ++j) {
|
for (TextBlock::TextWords::const_iterator j = t->_words.cbegin(), en = t->_words.cend(), f = j; j != en; ++j) {
|
||||||
bool wordEndsHere = (j->width >= 0);
|
bool wordEndsHere = (j->width >= 0);
|
||||||
QFixed j_width = wordEndsHere ? j->width : -j->width;
|
QFixed j_width = wordEndsHere ? j->width : -j->width;
|
||||||
|
@ -1131,9 +1123,9 @@ public:
|
||||||
longWordLine = false;
|
longWordLine = false;
|
||||||
}
|
}
|
||||||
if (wordEndsHere || longWordLine) {
|
if (wordEndsHere || longWordLine) {
|
||||||
|
f = j + 1;
|
||||||
f_wLeft = _wLeft;
|
f_wLeft = _wLeft;
|
||||||
f_lineHeight = _lineHeight;
|
f_lineHeight = _lineHeight;
|
||||||
f = j + 1;
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1143,6 +1135,7 @@ public:
|
||||||
if (elidedLine) {
|
if (elidedLine) {
|
||||||
_lineHeight = elidedLineHeight;
|
_lineHeight = elidedLineHeight;
|
||||||
} else if (f != j) {
|
} else if (f != j) {
|
||||||
|
// word did not fit completely, so we roll back the state to the beginning of this long word
|
||||||
j = f;
|
j = f;
|
||||||
_wLeft = f_wLeft;
|
_wLeft = f_wLeft;
|
||||||
_lineHeight = f_lineHeight;
|
_lineHeight = f_lineHeight;
|
||||||
|
@ -1166,6 +1159,28 @@ public:
|
||||||
f_wLeft = _wLeft;
|
f_wLeft = _wLeft;
|
||||||
f_lineHeight = _lineHeight;
|
f_lineHeight = _lineHeight;
|
||||||
}
|
}
|
||||||
|
if (lpadding > 0) { // no words in this block, spaces only
|
||||||
|
int32 elidedLineHeight = qMax(_lineHeight, blockHeight);
|
||||||
|
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yTo);
|
||||||
|
if (elidedLine) {
|
||||||
|
_lineHeight = elidedLineHeight;
|
||||||
|
}
|
||||||
|
ushort nextStart = _blockEnd(_t, i, e);
|
||||||
|
if (!drawLine(nextStart, i + 1, e)) return;
|
||||||
|
_y += _lineHeight;
|
||||||
|
_lineHeight = qMax(0, blockHeight);
|
||||||
|
_lineStart = nextStart;
|
||||||
|
_lineStartBlock = blockIndex + 1;
|
||||||
|
|
||||||
|
last_rBearing = _rb;
|
||||||
|
last_rPadding = b->rpadding();
|
||||||
|
_wLeft = _w;
|
||||||
|
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
|
||||||
|
_wLeft -= _elideRemoveFromEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
longWordLine = true;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2553,7 +2568,7 @@ void Text::setMarkedText(style::font font, const QString &text, const EntitiesIn
|
||||||
_font = font;
|
_font = font;
|
||||||
clean();
|
clean();
|
||||||
{
|
{
|
||||||
// QByteArray ba = text.toUtf8();
|
// QByteArray ba = text.toUtf8(); // chars for OS X crash investigation
|
||||||
// const char *ch = ba.constData();
|
// const char *ch = ba.constData();
|
||||||
// LOG(("STR: %1").arg(text));
|
// LOG(("STR: %1").arg(text));
|
||||||
// LOG(("BYTES: %1").arg(mb(ba.constData(), ba.size()).str()));
|
// LOG(("BYTES: %1").arg(mb(ba.constData(), ba.size()).str()));
|
||||||
|
@ -2562,6 +2577,36 @@ void Text::setMarkedText(style::font font, const QString &text, const EntitiesIn
|
||||||
// }
|
// }
|
||||||
// int32 w = _font->width(text);
|
// int32 w = _font->width(text);
|
||||||
|
|
||||||
|
// QString newText; // utf16 of the text for emoji
|
||||||
|
// newText.reserve(8 * text.size());
|
||||||
|
// for (const QChar *ch = text.constData(), *e = ch + text.size(); ch != e; ++ch) {
|
||||||
|
// if (chIsNewline(*ch)) {
|
||||||
|
// newText.append(*ch);
|
||||||
|
// } else {
|
||||||
|
// if (ch->isHighSurrogate() || ch->isLowSurrogate()) {
|
||||||
|
// if (ch->isHighSurrogate() && (ch + 1 != e) && ((ch + 1)->isLowSurrogate())) {
|
||||||
|
// newText.append("0x").append(QString::number((uint32(ch->unicode()) << 16) | uint32((ch + 1)->unicode()), 16).toUpper()).append("LLU,");
|
||||||
|
// ++ch;
|
||||||
|
// } else {
|
||||||
|
// newText.append("BADx").append(QString::number(ch->unicode(), 16).toUpper()).append("LLU,");
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// newText.append("0x").append(QString::number(ch->unicode(), 16).toUpper()).append("LLU,");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// newText.append("\n\n").append(text);
|
||||||
|
// TextParser parser(this, newText, EntitiesInText(), options);
|
||||||
|
|
||||||
|
// QString newText; // utf8 of the text for emoji sequences
|
||||||
|
// newText.reserve(8 * text.size());
|
||||||
|
// QByteArray ba = text.toUtf8();
|
||||||
|
// for (int32 i = 0, l = ba.size(); i < l; ++i) {
|
||||||
|
// newText.append("\\x").append(QString::number(uchar(ba.at(i)), 16).toLower());
|
||||||
|
// }
|
||||||
|
// newText.append("\n\n").append(text);
|
||||||
|
// TextParser parser(this, newText, EntitiesInText(), options);
|
||||||
|
|
||||||
TextParser parser(this, text, entities, options);
|
TextParser parser(this, text, entities, options);
|
||||||
}
|
}
|
||||||
recountNaturalSize(true, options.dir);
|
recountNaturalSize(true, options.dir);
|
||||||
|
|
|
@ -698,7 +698,7 @@ inline bool chIsDiac(QChar ch) { // diac and variation selectors
|
||||||
return (ch.category() == QChar::Mark_NonSpacing) || (ch.unicode() == 1652);
|
return (ch.category() == QChar::Mark_NonSpacing) || (ch.unicode() == 1652);
|
||||||
}
|
}
|
||||||
inline bool chIsBad(QChar ch) {
|
inline bool chIsBad(QChar ch) {
|
||||||
return (ch == 0) || (ch >= 8232 && ch < 8237) || (ch >= 65024 && ch < 65040 && ch != 65039) || (ch >= 127 && ch < 160 && ch != 156) || (cPlatform() == dbipMac && ch >= 0x0B00 && ch <= 0x0B7F && chIsDiac(ch) && QSysInfo::macVersion() >= QSysInfo::MV_10_11); // tmp hack see https://bugreports.qt.io/browse/QTBUG-48910
|
return (ch == 0) || (ch >= 8232 && ch < 8237) || (ch >= 65024 && ch < 65040 && ch != 65039) || (ch >= 127 && ch < 160 && ch != 156) || (cPlatform() == dbipMac && ch >= 0x0B00 && ch <= 0x0B7F && chIsDiac(ch) && cIsElCapitan()); // tmp hack see https://bugreports.qt.io/browse/QTBUG-48910
|
||||||
}
|
}
|
||||||
inline bool chIsTrimmed(QChar ch, bool rich = false) {
|
inline bool chIsTrimmed(QChar ch, bool rich = false) {
|
||||||
return (!rich || ch != TextCommand) && (chIsSpace(ch) || chIsBad(ch));
|
return (!rich || ch != TextCommand) && (chIsSpace(ch) || chIsBad(ch));
|
||||||
|
|
|
@ -150,7 +150,7 @@ void historyInit() {
|
||||||
_initTextOptions();
|
_initTextOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void startGif(HistoryItem *row, const QString &file) {
|
void startGif(HistoryItem *row, const FileLocation &file) {
|
||||||
if (row == animated.msg) {
|
if (row == animated.msg) {
|
||||||
stopGif();
|
stopGif();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,7 +24,7 @@ void historyInit();
|
||||||
|
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
|
|
||||||
void startGif(HistoryItem *row, const QString &file);
|
void startGif(HistoryItem *row, const FileLocation &file);
|
||||||
void itemRemovedGif(HistoryItem *item);
|
void itemRemovedGif(HistoryItem *item);
|
||||||
void itemReplacedGif(HistoryItem *oldItem, HistoryItem *newItem);
|
void itemReplacedGif(HistoryItem *oldItem, HistoryItem *newItem);
|
||||||
void stopGif();
|
void stopGif();
|
||||||
|
|
|
@ -874,6 +874,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
isUponSelected = hasSelected;
|
isUponSelected = hasSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_menu = new PopupMenu();
|
||||||
|
|
||||||
_contextMenuLnk = textlnkOver();
|
_contextMenuLnk = textlnkOver();
|
||||||
HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
|
HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
|
||||||
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
||||||
|
@ -881,7 +883,6 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
if (lnkPhoto || lnkVideo || lnkAudio || lnkDocument) {
|
if (lnkPhoto || lnkVideo || lnkAudio || lnkDocument) {
|
||||||
_menu = new PopupMenu();
|
|
||||||
if (isUponSelected > 0) {
|
if (isUponSelected > 0) {
|
||||||
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -897,7 +898,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
||||||
_menu->addAction(lang(cPlatform() == dbipMac ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
||||||
|
@ -931,59 +932,49 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
HistoryServiceMsg *srv = dynamic_cast<HistoryServiceMsg*>(item);
|
HistoryServiceMsg *srv = dynamic_cast<HistoryServiceMsg*>(item);
|
||||||
|
|
||||||
if (isUponSelected > 0) {
|
if (isUponSelected > 0) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
||||||
if (item && item->id > 0 && isUponSelected != 2 && canSendMessages) {
|
if (item && item->id > 0 && isUponSelected != 2 && canSendMessages) {
|
||||||
_menu->addAction(lang(lng_context_reply_msg), _widget, SLOT(onReplyToMessage()));
|
_menu->addAction(lang(lng_context_reply_msg), _widget, SLOT(onReplyToMessage()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (item && item->id > 0 && isUponSelected != -2 && canSendMessages) {
|
if (item && item->id > 0 && isUponSelected != -2 && canSendMessages) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_reply_msg), _widget, SLOT(onReplyToMessage()));
|
_menu->addAction(lang(lng_context_reply_msg), _widget, SLOT(onReplyToMessage()));
|
||||||
}
|
}
|
||||||
if (item && !isUponSelected && !_contextMenuLnk) {
|
if (item && !isUponSelected && !_contextMenuLnk) {
|
||||||
if (HistorySticker *sticker = dynamic_cast<HistorySticker*>(msg ? msg->getMedia() : 0)) {
|
if (HistorySticker *sticker = dynamic_cast<HistorySticker*>(msg ? msg->getMedia() : 0)) {
|
||||||
DocumentData *doc = sticker->document();
|
DocumentData *doc = sticker->document();
|
||||||
if (doc && doc->sticker() && doc->sticker()->set.type() != mtpc_inputStickerSetEmpty) {
|
if (doc && doc->sticker() && doc->sticker()->set.type() != mtpc_inputStickerSetEmpty) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(doc->sticker()->setInstalled() ? lng_context_pack_info : lng_context_pack_add), _widget, SLOT(onStickerPackInfo()));
|
_menu->addAction(lang(doc->sticker()->setInstalled() ? lng_context_pack_info : lng_context_pack_add), _widget, SLOT(onStickerPackInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QString contextMenuText = item->selectedText(FullItemSel);
|
QString contextMenuText = item->selectedText(FullItemSel);
|
||||||
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
|
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_contextMenuLnk && dynamic_cast<TextLink*>(_contextMenuLnk.data())) {
|
if (_contextMenuLnk && dynamic_cast<TextLink*>(_contextMenuLnk.data())) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_open_link), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_link), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_context_copy_link), this, SLOT(copyContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_link), this, SLOT(copyContextUrl()))->setEnabled(true);
|
||||||
} else if (_contextMenuLnk && dynamic_cast<EmailLink*>(_contextMenuLnk.data())) {
|
} else if (_contextMenuLnk && dynamic_cast<EmailLink*>(_contextMenuLnk.data())) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_open_email), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_email), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_context_copy_email), this, SLOT(copyContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_email), this, SLOT(copyContextUrl()))->setEnabled(true);
|
||||||
} else if (_contextMenuLnk && dynamic_cast<MentionLink*>(_contextMenuLnk.data())) {
|
} else if (_contextMenuLnk && dynamic_cast<MentionLink*>(_contextMenuLnk.data())) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_open_mention), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_mention), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_context_copy_mention), this, SLOT(copyContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_mention), this, SLOT(copyContextUrl()))->setEnabled(true);
|
||||||
} else if (_contextMenuLnk && dynamic_cast<HashtagLink*>(_contextMenuLnk.data())) {
|
} else if (_contextMenuLnk && dynamic_cast<HashtagLink*>(_contextMenuLnk.data())) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_open_hashtag), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_hashtag), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_context_copy_hashtag), this, SLOT(copyContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_hashtag), this, SLOT(copyContextUrl()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
if (isUponSelected > 1) {
|
if (isUponSelected > 1) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_forward_selected), _widget, SLOT(onForwardSelected()));
|
_menu->addAction(lang(lng_context_forward_selected), _widget, SLOT(onForwardSelected()));
|
||||||
if (selectedForDelete == selectedForForward) {
|
if (selectedForDelete == selectedForForward) {
|
||||||
_menu->addAction(lang(lng_context_delete_selected), _widget, SLOT(onDeleteSelected()));
|
_menu->addAction(lang(lng_context_delete_selected), _widget, SLOT(onDeleteSelected()));
|
||||||
}
|
}
|
||||||
_menu->addAction(lang(lng_context_clear_selection), _widget, SLOT(onClearSelected()));
|
_menu->addAction(lang(lng_context_clear_selection), _widget, SLOT(onClearSelected()));
|
||||||
} else if (item && ((isUponSelected != -2 && (canForward || canDelete)) || item->id > 0)) {
|
} else if (item && ((isUponSelected != -2 && (canForward || canDelete)) || item->id > 0)) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
if (isUponSelected != -2) {
|
if (isUponSelected != -2) {
|
||||||
if (canForward) {
|
if (canForward) {
|
||||||
_menu->addAction(lang(lng_context_forward_msg), _widget, SLOT(forwardMessage()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_forward_msg), _widget, SLOT(forwardMessage()))->setEnabled(true);
|
||||||
|
@ -998,7 +989,6 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (App::mousedItem() && !App::mousedItem()->serviceMsg() && App::mousedItem()->id > 0) {
|
if (App::mousedItem() && !App::mousedItem()->serviceMsg() && App::mousedItem()->id > 0) {
|
||||||
if (!_menu) _menu = new PopupMenu();
|
|
||||||
_menu->addAction(lang(lng_context_select_msg), _widget, SLOT(selectMessage()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_select_msg), _widget, SLOT(selectMessage()))->setEnabled(true);
|
||||||
item = App::mousedItem();
|
item = App::mousedItem();
|
||||||
}
|
}
|
||||||
|
@ -1006,7 +996,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
App::contextItem(item);
|
App::contextItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_menu) {
|
if (_menu->actions().isEmpty()) {
|
||||||
|
delete _menu;
|
||||||
|
_menu = 0;
|
||||||
|
} else {
|
||||||
connect(_menu, SIGNAL(destroyed(QObject*)), this, SLOT(onMenuDestroy(QObject*)));
|
connect(_menu, SIGNAL(destroyed(QObject*)), this, SLOT(onMenuDestroy(QObject*)));
|
||||||
_menu->popup(e->globalPos());
|
_menu->popup(e->globalPos());
|
||||||
e->accept();
|
e->accept();
|
||||||
|
@ -2943,7 +2936,8 @@ void HistoryWidget::updateStickers() {
|
||||||
if (cLastStickersUpdate() && getms(true) < cLastStickersUpdate() + StickersUpdateTimeout) return;
|
if (cLastStickersUpdate() && getms(true) < cLastStickersUpdate() + StickersUpdateTimeout) return;
|
||||||
if (_stickersUpdateRequest) return;
|
if (_stickersUpdateRequest) return;
|
||||||
|
|
||||||
_stickersUpdateRequest = MTP::send(MTPmessages_GetAllStickers(MTP_string(cStickersHash())), rpcDone(&HistoryWidget::stickersGot), rpcFail(&HistoryWidget::stickersFailed));
|
cSetStickersHash(stickersCountHash(true));
|
||||||
|
_stickersUpdateRequest = MTP::send(MTPmessages_GetAllStickers(MTP_int(cStickersHash())), rpcDone(&HistoryWidget::stickersGot), rpcFail(&HistoryWidget::stickersFailed));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::notifyBotCommandsChanged(UserData *user) {
|
void HistoryWidget::notifyBotCommandsChanged(UserData *user) {
|
||||||
|
@ -2993,9 +2987,6 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
||||||
|
|
||||||
const QVector<MTPStickerSet> &d_sets(d.vsets.c_vector().v);
|
const QVector<MTPStickerSet> &d_sets(d.vsets.c_vector().v);
|
||||||
|
|
||||||
QByteArray wasHash = cStickersHash();
|
|
||||||
cSetStickersHash(qba(d.vhash));
|
|
||||||
|
|
||||||
StickerSetsOrder &setsOrder(cRefStickerSetsOrder());
|
StickerSetsOrder &setsOrder(cRefStickerSetsOrder());
|
||||||
setsOrder.clear();
|
setsOrder.clear();
|
||||||
|
|
||||||
|
@ -3008,21 +2999,9 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
||||||
if (d_sets.at(i).type() == mtpc_stickerSet) {
|
if (d_sets.at(i).type() == mtpc_stickerSet) {
|
||||||
const MTPDstickerSet &set(d_sets.at(i).c_stickerSet());
|
const MTPDstickerSet &set(d_sets.at(i).c_stickerSet());
|
||||||
StickerSets::iterator i = sets.find(set.vid.v);
|
StickerSets::iterator i = sets.find(set.vid.v);
|
||||||
QString title = qs(set.vtitle);
|
QString title = stickerSetTitle(set);
|
||||||
if (set.vflags.v & MTPDstickerSet::flag_official) {
|
|
||||||
if (!title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) {
|
|
||||||
title = lang(lng_stickers_default_set);
|
|
||||||
}
|
|
||||||
setsOrder.push_front(set.vid.v);
|
|
||||||
} else {
|
|
||||||
setsOrder.push_back(set.vid.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == sets.cend()) {
|
if (i == sets.cend()) {
|
||||||
i = sets.insert(set.vid.v, StickerSet(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_flag_NOT_LOADED));
|
i = sets.insert(set.vid.v, StickerSet(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_flag_NOT_LOADED));
|
||||||
if (!(i->flags & MTPDstickerSet::flag_disabled)) {
|
|
||||||
setsToRequest.insert(set.vid.v, set.vaccess_hash.v);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
i->access = set.vaccess_hash.v;
|
i->access = set.vaccess_hash.v;
|
||||||
i->title = title;
|
i->title = title;
|
||||||
|
@ -3032,20 +3011,39 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
||||||
i->count = set.vcount.v;
|
i->count = set.vcount.v;
|
||||||
i->hash = set.vhash.v;
|
i->hash = set.vhash.v;
|
||||||
i->flags |= MTPDstickerSet_flag_NOT_LOADED; // need to request this set
|
i->flags |= MTPDstickerSet_flag_NOT_LOADED; // need to request this set
|
||||||
if (!(i->flags & MTPDstickerSet::flag_disabled)) {
|
}
|
||||||
|
}
|
||||||
|
if (!(i->flags & MTPDstickerSet::flag_disabled) || (i->flags & MTPDstickerSet::flag_official)) {
|
||||||
|
setsOrder.push_back(set.vid.v);
|
||||||
|
if (i->stickers.isEmpty() || (i->flags & MTPDstickerSet_flag_NOT_LOADED)) {
|
||||||
setsToRequest.insert(set.vid.v, set.vaccess_hash.v);
|
setsToRequest.insert(set.vid.v, set.vaccess_hash.v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
bool writeRecent = false;
|
||||||
for (StickerSets::iterator i = sets.begin(), e = sets.end(); i != e;) {
|
RecentStickerPack &recent(cGetRecentStickers());
|
||||||
if (i->id == CustomStickerSetId || i->access != 0) {
|
for (StickerSets::iterator it = sets.begin(), e = sets.end(); it != e;) {
|
||||||
++i;
|
if (it->id == CustomStickerSetId || it->access != 0) {
|
||||||
|
++it;
|
||||||
} else {
|
} else {
|
||||||
i = sets.erase(i);
|
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
||||||
|
if (it->stickers.indexOf(i->first) >= 0) {
|
||||||
|
i = recent.erase(i);
|
||||||
|
writeRecent = true;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
it = sets.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 countedHash = stickersCountHash();
|
||||||
|
cSetStickersHash(countedHash);
|
||||||
|
if (countedHash != d.vhash.v) {
|
||||||
|
LOG(("API Error: received stickers hash %1 while counted hash is %2").arg(d.vhash.v).arg(countedHash));
|
||||||
|
}
|
||||||
|
|
||||||
if (!setsToRequest.isEmpty() && App::api()) {
|
if (!setsToRequest.isEmpty() && App::api()) {
|
||||||
for (QMap<uint64, uint64>::const_iterator i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) {
|
for (QMap<uint64, uint64>::const_iterator i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) {
|
||||||
|
@ -3055,6 +3053,7 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Local::writeStickers();
|
Local::writeStickers();
|
||||||
|
if (writeRecent) Local::writeUserSettings();
|
||||||
|
|
||||||
if (App::main()) emit App::main()->stickersUpdated();
|
if (App::main()) emit App::main()->stickersUpdated();
|
||||||
}
|
}
|
||||||
|
@ -3217,6 +3216,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
|
|
||||||
if (_history) {
|
if (_history) {
|
||||||
_history->draft = _field.getLastText();
|
_history->draft = _field.getLastText();
|
||||||
|
if (_migrated) _migrated->draft = QString(); // use migrated draft only once
|
||||||
_history->draftCursor.fillFrom(_field);
|
_history->draftCursor.fillFrom(_field);
|
||||||
_history->draftToId = _replyToId;
|
_history->draftToId = _replyToId;
|
||||||
_history->draftPreviewCancelled = _previewCancelled;
|
_history->draftPreviewCancelled = _previewCancelled;
|
||||||
|
@ -3326,6 +3326,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
_history->draftCursor = _migrated->draftCursor;
|
_history->draftCursor = _migrated->draftCursor;
|
||||||
_history->draftPreviewCancelled = _migrated->draftPreviewCancelled;
|
_history->draftPreviewCancelled = _migrated->draftPreviewCancelled;
|
||||||
_history->draftToId = 0;
|
_history->draftToId = 0;
|
||||||
|
_migrated->draft = QString(); // use migrated draft only once
|
||||||
applyDraft(false);
|
applyDraft(false);
|
||||||
_replyToId = 0;
|
_replyToId = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -4246,7 +4247,7 @@ void HistoryWidget::blockDone(PeerData *peer, const MTPBool &result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onBotStart() {
|
void HistoryWidget::onBotStart() {
|
||||||
if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo) {
|
if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo || !_canSendMessages) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4813,7 +4814,7 @@ bool HistoryWidget::hasBroadcastToggle() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::isBotStart() const {
|
bool HistoryWidget::isBotStart() const {
|
||||||
if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo) return false;
|
if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo || !_canSendMessages) return false;
|
||||||
return !_peer->asUser()->botInfo->startToken.isEmpty() || (_history->isEmpty() && !_history->lastMsg);
|
return !_peer->asUser()->botInfo->startToken.isEmpty() || (_history->isEmpty() && !_history->lastMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5291,11 +5292,12 @@ void HistoryWidget::cancelSendFile(const FileLoadResultPtr &file) {
|
||||||
void HistoryWidget::confirmShareContact(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter) {
|
void HistoryWidget::confirmShareContact(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter) {
|
||||||
if (!_peer) return;
|
if (!_peer) return;
|
||||||
|
|
||||||
|
PeerId shareToId = _peer->id;
|
||||||
if (_confirmWithTextId == 0xFFFFFFFFFFFFFFFFL) {
|
if (_confirmWithTextId == 0xFFFFFFFFFFFFFFFFL) {
|
||||||
onSend(ctrlShiftEnter, replyTo);
|
onSend(ctrlShiftEnter, replyTo);
|
||||||
_confirmWithTextId = 0;
|
_confirmWithTextId = 0;
|
||||||
}
|
}
|
||||||
shareContact(_peer->id, phone, fname, lname, replyTo);
|
shareContact(shareToId, phone, fname, lname, replyTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::cancelShareContact() {
|
void HistoryWidget::cancelShareContact() {
|
||||||
|
@ -5893,7 +5895,7 @@ void HistoryWidget::updateBotKeyboard(History *h) {
|
||||||
if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) {
|
if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) {
|
||||||
_history->lastKeyboardHiddenId = _history->lastKeyboardId;
|
_history->lastKeyboardHiddenId = _history->lastKeyboardId;
|
||||||
}
|
}
|
||||||
if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (!_field.hasSendText() && !kbWasHidden()))) {
|
if (!isBotStart() && !isBlocked() && _canSendMessages && (wasVisible || _replyTo || (!_field.hasSendText() && !kbWasHidden()))) {
|
||||||
if (!_a_show.animating()) {
|
if (!_a_show.animating()) {
|
||||||
if (hasMarkup) {
|
if (hasMarkup) {
|
||||||
_kbScroll.show();
|
_kbScroll.show();
|
||||||
|
|
|
@ -85,8 +85,8 @@ QString Translator::translate(const char *context, const char *sourceText, const
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
if (qstr("QWidgetTextControl") == context || qstr("QLineEdit") == context) {
|
if (qstr("QWidgetTextControl") == context || qstr("QLineEdit") == context) {
|
||||||
if (qstr("&Undo") == sourceText) return lang((cPlatform() == dbipWindows) ? lng_wnd_menu_undo : ((cPlatform() == dbipMac) ? lng_mac_menu_undo : lng_linux_menu_undo));
|
if (qstr("&Undo") == sourceText) return lang((cPlatform() == dbipWindows) ? lng_wnd_menu_undo : ((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_mac_menu_undo : lng_linux_menu_undo));
|
||||||
if (qstr("&Redo") == sourceText) return lang((cPlatform() == dbipWindows) ? lng_wnd_menu_redo : ((cPlatform() == dbipMac) ? lng_mac_menu_redo : lng_linux_menu_redo));
|
if (qstr("&Redo") == sourceText) return lang((cPlatform() == dbipWindows) ? lng_wnd_menu_redo : ((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_mac_menu_redo : lng_linux_menu_redo));
|
||||||
if (qstr("Cu&t") == sourceText) return lang(lng_mac_menu_cut);
|
if (qstr("Cu&t") == sourceText) return lang(lng_mac_menu_cut);
|
||||||
if (qstr("&Copy") == sourceText) return lang(lng_mac_menu_copy);
|
if (qstr("&Copy") == sourceText) return lang(lng_mac_menu_copy);
|
||||||
if (qstr("&Paste") == sourceText) return lang(lng_mac_menu_paste);
|
if (qstr("&Paste") == sourceText) return lang(lng_mac_menu_paste);
|
||||||
|
|
|
@ -431,6 +431,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_channel_add_admins" = "Neuer Administrator";
|
"lng_channel_add_admins" = "Neuer Administrator";
|
||||||
"lng_channel_add_members" = "Mitglieder hinzufügen";
|
"lng_channel_add_members" = "Mitglieder hinzufügen";
|
||||||
"lng_channel_members" = "Mitglieder";
|
"lng_channel_members" = "Mitglieder";
|
||||||
|
"lng_channel_only_last_shown" = "Nur {count:_not_used_|# letztes Mitglied wird angezeigt|letzte # Mitglieder werden angezeigt}";
|
||||||
"lng_channel_admins" = "Administratoren";
|
"lng_channel_admins" = "Administratoren";
|
||||||
"lng_channel_add_admin" = "Administrator hinzufügen";
|
"lng_channel_add_admin" = "Administrator hinzufügen";
|
||||||
"lng_channel_admin_sure" = "Soll {user} Administrator werden?";
|
"lng_channel_admin_sure" = "Soll {user} Administrator werden?";
|
||||||
|
@ -564,10 +565,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_emoji_category1" = "Personen";
|
"lng_emoji_category1" = "Personen";
|
||||||
"lng_emoji_category2" = "Natur";
|
"lng_emoji_category2" = "Natur";
|
||||||
"lng_emoji_category3" = "Essen & Trinken";
|
"lng_emoji_category3" = "Essen & Trinken";
|
||||||
"lng_emoji_category4" = "Feiern";
|
"lng_emoji_category4" = "Aktivitäten";
|
||||||
"lng_emoji_category5" = "Aktivität";
|
"lng_emoji_category5" = "Reisen & Orte";
|
||||||
"lng_emoji_category6" = "Reisen & Orte";
|
"lng_emoji_category6" = "Objekte";
|
||||||
"lng_emoji_category7" = "Objekte & Symbole";
|
"lng_emoji_category7" = "Symbole & Flaggen";
|
||||||
|
|
||||||
"lng_switch_stickers" = "Sticker";
|
"lng_switch_stickers" = "Sticker";
|
||||||
"lng_switch_emoji" = "Emoji";
|
"lng_switch_emoji" = "Emoji";
|
||||||
|
@ -581,6 +582,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_not_found" = "Sticker-Paket nicht gefunden.";
|
"lng_stickers_not_found" = "Sticker-Paket nicht gefunden.";
|
||||||
"lng_stickers_copied" = "Sticker-Paket Link in die Zwischenablage kopiert.";
|
"lng_stickers_copied" = "Sticker-Paket Link in die Zwischenablage kopiert.";
|
||||||
"lng_stickers_default_set" = "Große Denker";
|
"lng_stickers_default_set" = "Große Denker";
|
||||||
|
"lng_stickers_you_have" = "Sticker-Pakete verwalten";
|
||||||
|
"lng_stickers_packs" = "Sticker-Pakete";
|
||||||
|
"lng_stickers_reorder" = "Paket gedrückt halten und verschieben um die Anordnung zu ändern";
|
||||||
|
"lng_stickers_remove" = "Löschen";
|
||||||
|
"lng_stickers_return" = "Rückgängig";
|
||||||
|
"lng_stickers_restore" = "Zeigen";
|
||||||
|
"lng_stickers_count" = "{count:Lade..|# Sticker|# Sticker}";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "Bild";
|
"lng_in_dlg_photo" = "Bild";
|
||||||
"lng_in_dlg_video" = "Video";
|
"lng_in_dlg_video" = "Video";
|
||||||
|
@ -658,6 +666,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
"lng_choose_images" = "Bilder auswählen";
|
"lng_choose_images" = "Bilder auswählen";
|
||||||
|
|
||||||
|
"lng_context_view_profile" = "Profil öffnen";
|
||||||
|
"lng_context_view_group" = "Gruppeninfo zeigen";
|
||||||
|
"lng_context_view_channel" = "Kanalinfo anzeigen";
|
||||||
|
|
||||||
"lng_context_open_link" = "Link öffnen";
|
"lng_context_open_link" = "Link öffnen";
|
||||||
"lng_context_copy_link" = "Link kopieren";
|
"lng_context_copy_link" = "Link kopieren";
|
||||||
"lng_context_open_email" = "Email verfassen";
|
"lng_context_open_email" = "Email verfassen";
|
||||||
|
@ -789,7 +801,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
|
||||||
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
||||||
"lng_new_version_text" = "— Gruppen erlauben ab sofort Administratoren: Diese können den Gruppennamen und das Bild ändern sowie Mitglieder hinzufügen und auch wieder entfernen\n— Gruppen, die das Limit von 200 Mitgliedern erreicht haben, können in eine Supergruppe (1000 Mitglieder) geändert werden\n\nAusführliche Informationen zu den neuen Supergruppen:\n{link}\n\nUnseren deutschsprachigen Infokanal findest du hier: https://telegram.me/TelegramDE";
|
"lng_new_version_text" = "— Sticker-Verwaltung: Ändere die Sortierung deiner Sticker-Pakete, Sortierung wird auf all deinen Geräten synchronisiert \n— Sticker gedrückt halten vor dem Versand für eine Vorschau\n— Neues Kontextmenü für Chats in der Chatliste \n— Neue Emoji werden unterstützt\n\nUnseren deutschsprachigen Infokanal findest du hier: https://telegram.me/TelegramDE";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
||||||
|
|
||||||
|
|
|
@ -407,10 +407,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_set_group_photo" = "Poner foto";
|
"lng_profile_set_group_photo" = "Poner foto";
|
||||||
"lng_profile_add_participant" = "Añadir miembros";
|
"lng_profile_add_participant" = "Añadir miembros";
|
||||||
"lng_profile_delete_and_exit" = "Dejar grupo";
|
"lng_profile_delete_and_exit" = "Dejar grupo";
|
||||||
"lng_profile_kick" = "Expulsar";
|
"lng_profile_kick" = "Eliminar";
|
||||||
"lng_profile_sure_kick" = "¿Expulsar a {user} del grupo?";
|
"lng_profile_sure_kick" = "¿Eliminar a {user} del grupo?";
|
||||||
"lng_profile_sure_kick_channel" = "¿Expulsar a {user} del canal?";
|
"lng_profile_sure_kick_channel" = "¿Eliminar a {user} del canal?";
|
||||||
"lng_profile_sure_kick_admin" = "¿Expulsar a {user} de los administradores?";
|
"lng_profile_sure_kick_admin" = "¿Eliminar a {user} de los administradores?";
|
||||||
"lng_profile_loading" = "Cargando...";
|
"lng_profile_loading" = "Cargando...";
|
||||||
"lng_profile_shared_media" = "Multimedia";
|
"lng_profile_shared_media" = "Multimedia";
|
||||||
"lng_profile_no_media" = "No hay multimedia en este chat.";
|
"lng_profile_no_media" = "No hay multimedia en este chat.";
|
||||||
|
@ -431,6 +431,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_channel_add_admins" = "Nuevo administrador";
|
"lng_channel_add_admins" = "Nuevo administrador";
|
||||||
"lng_channel_add_members" = "Añadir miembros";
|
"lng_channel_add_members" = "Añadir miembros";
|
||||||
"lng_channel_members" = "Miembros";
|
"lng_channel_members" = "Miembros";
|
||||||
|
"lng_channel_only_last_shown" = "Sólo {count:_not_used_|aparece el último miembro|aparecen los últimos # miembros}";
|
||||||
"lng_channel_admins" = "Administradores";
|
"lng_channel_admins" = "Administradores";
|
||||||
"lng_channel_add_admin" = "Añadir administrador";
|
"lng_channel_add_admin" = "Añadir administrador";
|
||||||
"lng_channel_admin_sure" = "¿Añadir a {user} como administrador?";
|
"lng_channel_admin_sure" = "¿Añadir a {user} como administrador?";
|
||||||
|
@ -438,7 +439,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_chat_all_members_admins" = "Todos son administradores";
|
"lng_chat_all_members_admins" = "Todos son administradores";
|
||||||
"lng_chat_about_all_admins" = "Todos pueden añadir nuevos miembros, editar el nombre y la foto del grupo.";
|
"lng_chat_about_all_admins" = "Todos pueden añadir nuevos miembros, editar el nombre y la foto del grupo.";
|
||||||
"lng_chat_about_admins" = "Sólo los administradores pueden añadir y quitar miembros, editar el nombre y la foto del grupo.";
|
"lng_chat_about_admins" = "Sólo los administradores pueden añadir y eliminar miembros, editar el nombre y la foto del grupo.";
|
||||||
|
|
||||||
"lng_participant_filter" = "Buscar";
|
"lng_participant_filter" = "Buscar";
|
||||||
"lng_participant_invite" = "Invitar";
|
"lng_participant_invite" = "Invitar";
|
||||||
|
@ -447,7 +448,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "Siguiente";
|
"lng_create_group_next" = "Siguiente";
|
||||||
"lng_create_group_create" = "Crear";
|
"lng_create_group_create" = "Crear";
|
||||||
"lng_create_group_title" = "Nuevo grupo";
|
"lng_create_group_title" = "Nuevo grupo";
|
||||||
"lng_create_group_about" = "Los grupos son ideales para las comunidades más pequeñas,\nde hasta {count:_not_used|# miembro|# miembros}";
|
"lng_create_group_about" = "Los grupos son ideales para las comunidades\nmás pequeñas, de hasta {count:_not_used|# miembro|# miembros}";
|
||||||
"lng_create_channel_title" = "Nuevo canal";
|
"lng_create_channel_title" = "Nuevo canal";
|
||||||
"lng_create_channel_about" = "Los canales permiten difundir tus mensajes a audiencias ilimitadas";
|
"lng_create_channel_about" = "Los canales permiten difundir tus mensajes a audiencias ilimitadas";
|
||||||
"lng_create_public_channel_title" = "Canal público";
|
"lng_create_public_channel_title" = "Canal público";
|
||||||
|
@ -477,9 +478,9 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_sure_delete_group_history" = "¿Quieres borrar todo el historial en «{group}»?\n\nEsta acción no se puede deshacer.";
|
"lng_sure_delete_group_history" = "¿Quieres borrar todo el historial en «{group}»?\n\nEsta acción no se puede deshacer.";
|
||||||
"lng_sure_delete_and_exit" = "¿Quieres eliminar todo el historial de mensajes y dejar el grupo «{group}»?\n\nEsta acción no se puede deshacer.";
|
"lng_sure_delete_and_exit" = "¿Quieres eliminar todo el historial de mensajes y dejar el grupo «{group}»?\n\nEsta acción no se puede deshacer.";
|
||||||
"lng_sure_leave_channel" = "¿Quieres dejar este canal?";
|
"lng_sure_leave_channel" = "¿Quieres dejar este canal?";
|
||||||
"lng_sure_delete_channel" = "¿Quieres eliminar este canal? Todos los miembros y mensajes serán eliminados.";
|
"lng_sure_delete_channel" = "¿Quieres eliminar este canal? Todos los miembros y mensajes se perderán.";
|
||||||
"lng_sure_leave_group" = "¿Quieres salir del grupo?\nNo puedes deshacer esta acción.";
|
"lng_sure_leave_group" = "¿Quieres salir del grupo?\nNo puedes deshacer esta acción.";
|
||||||
"lng_sure_delete_group" = "¿Quieres eliminar este grupo? Todos los miembros y mensajes serán eliminados.";
|
"lng_sure_delete_group" = "¿Quieres eliminar este grupo? Todos los miembros y mensajes se perderán.";
|
||||||
|
|
||||||
"lng_message_empty" = "Mensaje vacío";
|
"lng_message_empty" = "Mensaje vacío";
|
||||||
"lng_media_unsupported" = "Multimedia no soportada";
|
"lng_media_unsupported" = "Multimedia no soportada";
|
||||||
|
@ -492,12 +493,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_you_joined" = "Te uniste a este canal";
|
"lng_action_you_joined" = "Te uniste a este canal";
|
||||||
"lng_action_add_you_group" = "{from} te añadió al grupo";
|
"lng_action_add_you_group" = "{from} te añadió al grupo";
|
||||||
"lng_action_you_joined_group" = "Te uniste a este grupo";
|
"lng_action_you_joined_group" = "Te uniste a este grupo";
|
||||||
"lng_action_kick_user" = "{from} expulsó a {user}";
|
"lng_action_kick_user" = "{from} eliminó a {user}";
|
||||||
"lng_action_user_left" = "{from} dejó el grupo";
|
"lng_action_user_left" = "{from} dejó el grupo";
|
||||||
"lng_action_user_joined" = "{from} se unió al grupo";
|
"lng_action_user_joined" = "{from} se unió al grupo";
|
||||||
"lng_action_user_joined_by_link" = "{from} se unió al grupo con un enlace de invitación";
|
"lng_action_user_joined_by_link" = "{from} se unió al grupo con un enlace de invitación";
|
||||||
"lng_action_user_registered" = "{from} se acaba de unir a Telegram";
|
"lng_action_user_registered" = "{from} se acaba de unir a Telegram";
|
||||||
"lng_action_removed_photo" = "{from} quitó la foto del grupo";
|
"lng_action_removed_photo" = "{from} eliminó la foto del grupo";
|
||||||
"lng_action_removed_photo_channel" = "Foto del canal eliminada";
|
"lng_action_removed_photo_channel" = "Foto del canal eliminada";
|
||||||
"lng_action_changed_photo" = "{from} actualizó la foto del grupo";
|
"lng_action_changed_photo" = "{from} actualizó la foto del grupo";
|
||||||
"lng_action_changed_photo_channel" = "Foto del canal actualizada";
|
"lng_action_changed_photo_channel" = "Foto del canal actualizada";
|
||||||
|
@ -564,10 +565,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_emoji_category1" = "Personas";
|
"lng_emoji_category1" = "Personas";
|
||||||
"lng_emoji_category2" = "Naturaleza";
|
"lng_emoji_category2" = "Naturaleza";
|
||||||
"lng_emoji_category3" = "Comida y bebida";
|
"lng_emoji_category3" = "Comida y bebida";
|
||||||
"lng_emoji_category4" = "Celebración";
|
"lng_emoji_category4" = "Actividad";
|
||||||
"lng_emoji_category5" = "Actividad";
|
"lng_emoji_category5" = "Viajes y destinos";
|
||||||
"lng_emoji_category6" = "Viajes y destinos";
|
"lng_emoji_category6" = "Objetos";
|
||||||
"lng_emoji_category7" = "Objetos y símbolos";
|
"lng_emoji_category7" = "Símbolos y banderas";
|
||||||
|
|
||||||
"lng_switch_stickers" = "Stickers";
|
"lng_switch_stickers" = "Stickers";
|
||||||
"lng_switch_emoji" = "Emoji";
|
"lng_switch_emoji" = "Emoji";
|
||||||
|
@ -581,6 +582,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_not_found" = "Pack de stickers no encontrado.";
|
"lng_stickers_not_found" = "Pack de stickers no encontrado.";
|
||||||
"lng_stickers_copied" = "Enlace del pack de stickers copiado al portapapeles.";
|
"lng_stickers_copied" = "Enlace del pack de stickers copiado al portapapeles.";
|
||||||
"lng_stickers_default_set" = "Grandes personajes";
|
"lng_stickers_default_set" = "Grandes personajes";
|
||||||
|
"lng_stickers_you_have" = "Administrar y ordenar los packs de stickers";
|
||||||
|
"lng_stickers_packs" = "Packs de stickers";
|
||||||
|
"lng_stickers_reorder" = "Haz clic y arrastra para ordenar los packs";
|
||||||
|
"lng_stickers_remove" = "Eliminar";
|
||||||
|
"lng_stickers_return" = "Deshacer";
|
||||||
|
"lng_stickers_restore" = "Restaurar";
|
||||||
|
"lng_stickers_count" = "{count:Cargando...|# sticker|# stickers}";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "Foto";
|
"lng_in_dlg_photo" = "Foto";
|
||||||
"lng_in_dlg_video" = "Vídeo";
|
"lng_in_dlg_video" = "Vídeo";
|
||||||
|
@ -658,6 +666,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
"lng_choose_images" = "Elegir imágenes";
|
"lng_choose_images" = "Elegir imágenes";
|
||||||
|
|
||||||
|
"lng_context_view_profile" = "Ver información";
|
||||||
|
"lng_context_view_group" = "Ver información";
|
||||||
|
"lng_context_view_channel" = "Ver información";
|
||||||
|
|
||||||
"lng_context_open_link" = "Abrir enlace";
|
"lng_context_open_link" = "Abrir enlace";
|
||||||
"lng_context_copy_link" = "Copiar enlace";
|
"lng_context_copy_link" = "Copiar enlace";
|
||||||
"lng_context_open_email" = "Escribir a esta dirección";
|
"lng_context_open_email" = "Escribir a esta dirección";
|
||||||
|
@ -789,7 +801,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop ha sido actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop ha sido actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
|
||||||
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
|
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
|
||||||
"lng_new_version_text" = "– Los grupos ahora pueden tener múltiples administradores, con la habilidad de editar el nombre y foto de perfil, además de añadir y quitar miembros\n– Los grupos que alcanzan la capacidad de 200 usuarios pueden convertirse en supergrupos, que permiten hasta 1000 miembros\n\nMás sobre los administradores y supergrupos:\n{link}";
|
"lng_new_version_text" = "— Administra los stickers: ordena manualmente tus packs de stickers. El orden de los packs se sincronizará en todos tus dispositivos \n— Haz clic y mantén en un sticker para ver una vista previa antes de enviar\n— Nuevo menú contextual para los chats en la lista de chats \n— Soporte de todos los emojis existentes";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
||||||
|
|
||||||
|
|
|
@ -431,6 +431,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_channel_add_admins" = "Nuovo amministratore";
|
"lng_channel_add_admins" = "Nuovo amministratore";
|
||||||
"lng_channel_add_members" = "Aggiungi membri";
|
"lng_channel_add_members" = "Aggiungi membri";
|
||||||
"lng_channel_members" = "Membri";
|
"lng_channel_members" = "Membri";
|
||||||
|
"lng_channel_only_last_shown" = "Solo {count:_not_used_|l'ultimo membro è mostrato|gli ultimi # membri sono mostrati} qui";
|
||||||
"lng_channel_admins" = "Amministratori";
|
"lng_channel_admins" = "Amministratori";
|
||||||
"lng_channel_add_admin" = "Aggiungi amministratore";
|
"lng_channel_add_admin" = "Aggiungi amministratore";
|
||||||
"lng_channel_admin_sure" = "Aggiungere {user} agli amministratori?";
|
"lng_channel_admin_sure" = "Aggiungere {user} agli amministratori?";
|
||||||
|
@ -564,10 +565,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_emoji_category1" = "Persone";
|
"lng_emoji_category1" = "Persone";
|
||||||
"lng_emoji_category2" = "Natura";
|
"lng_emoji_category2" = "Natura";
|
||||||
"lng_emoji_category3" = "Cibo e bevande";
|
"lng_emoji_category3" = "Cibo e bevande";
|
||||||
"lng_emoji_category4" = "Festeggiamenti";
|
"lng_emoji_category4" = "Attività";
|
||||||
"lng_emoji_category5" = "Attività";
|
"lng_emoji_category5" = "Viaggi e luoghi";
|
||||||
"lng_emoji_category6" = "Viaggi e luoghi";
|
"lng_emoji_category6" = "Oggetti";
|
||||||
"lng_emoji_category7" = "Oggetti e simboli";
|
"lng_emoji_category7" = "Simboli e bandiere";
|
||||||
|
|
||||||
"lng_switch_stickers" = "Sticker";
|
"lng_switch_stickers" = "Sticker";
|
||||||
"lng_switch_emoji" = "Emoji";
|
"lng_switch_emoji" = "Emoji";
|
||||||
|
@ -578,9 +579,16 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_remove_pack" = "Rimuovere «{sticker_pack}»?";
|
"lng_stickers_remove_pack" = "Rimuovere «{sticker_pack}»?";
|
||||||
"lng_stickers_add_pack" = "Aggiungi sticker";
|
"lng_stickers_add_pack" = "Aggiungi sticker";
|
||||||
"lng_stickers_share_pack" = "Condividi sticker";
|
"lng_stickers_share_pack" = "Condividi sticker";
|
||||||
"lng_stickers_not_found" = "Pacchetto di sticker non trovato.";
|
"lng_stickers_not_found" = "Set di sticker non trovato.";
|
||||||
"lng_stickers_copied" = "Link degli sticker copiato negli appunti.";
|
"lng_stickers_copied" = "Link degli sticker copiato negli appunti.";
|
||||||
"lng_stickers_default_set" = "Grandi menti";
|
"lng_stickers_default_set" = "Grandi menti";
|
||||||
|
"lng_stickers_you_have" = "Organizza e riordina i set di sticker";
|
||||||
|
"lng_stickers_packs" = "Set di sticker";
|
||||||
|
"lng_stickers_reorder" = "Clicca e tieni premuto per riordinare i set di sticker";
|
||||||
|
"lng_stickers_remove" = "Elimina";
|
||||||
|
"lng_stickers_return" = "Annulla";
|
||||||
|
"lng_stickers_restore" = "Ripristina";
|
||||||
|
"lng_stickers_count" = "{count:Caricamento..|# sticker|# sticker}";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "Foto";
|
"lng_in_dlg_photo" = "Foto";
|
||||||
"lng_in_dlg_video" = "Video";
|
"lng_in_dlg_video" = "Video";
|
||||||
|
@ -658,6 +666,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
"lng_choose_images" = "Scegli immagini";
|
"lng_choose_images" = "Scegli immagini";
|
||||||
|
|
||||||
|
"lng_context_view_profile" = "Visualizza profilo";
|
||||||
|
"lng_context_view_group" = "Visualizza info gruppo";
|
||||||
|
"lng_context_view_channel" = "Visualizza info canale";
|
||||||
|
|
||||||
"lng_context_open_link" = "Apri link";
|
"lng_context_open_link" = "Apri link";
|
||||||
"lng_context_copy_link" = "Copia link";
|
"lng_context_copy_link" = "Copia link";
|
||||||
"lng_context_open_email" = "Scrivi a questo indirizzo";
|
"lng_context_open_email" = "Scrivi a questo indirizzo";
|
||||||
|
@ -789,7 +801,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}";
|
||||||
"lng_new_version_minor" = "— Bug fix e altri miglioramenti minori";
|
"lng_new_version_minor" = "— Bug fix e altri miglioramenti minori";
|
||||||
"lng_new_version_text" = "— I gruppi ora possono avere più amministratori con la possibilità di cambiare il nome e l'immagine, e di aggiungere e rimuovere membri\n— I gruppi che hanno raggiunto i 200 membri possono essere aggiornati a supergruppi e avere fino a 1000 membri\n\nPiù info su amministratori e supergruppi:\n{link}";
|
"lng_new_version_text" = "— Gestione degli sticker: Riordina manualmente i tuoi set di sticker, ora sono sincronizzati tra i tuoi dispositivi\n— Clicca e tieni premuto su uno sticker per visualizzare l'anteprima prima di inviarlo\n— Nuovo menu contestuale per le chat nella lista chat\n— Tutte le nuove emoji ora sono supportate";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
||||||
|
|
||||||
|
|
|
@ -431,6 +431,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_channel_add_admins" = "새로운 관리자";
|
"lng_channel_add_admins" = "새로운 관리자";
|
||||||
"lng_channel_add_members" = "구성원 추가";
|
"lng_channel_add_members" = "구성원 추가";
|
||||||
"lng_channel_members" = "구성원";
|
"lng_channel_members" = "구성원";
|
||||||
|
"lng_channel_only_last_shown" = "마지막 {count:_not_used_|# 구성원|# 구성원} 들이 표시가 됩니다.";
|
||||||
"lng_channel_admins" = "관리자";
|
"lng_channel_admins" = "관리자";
|
||||||
"lng_channel_add_admin" = "관리자 추가";
|
"lng_channel_add_admin" = "관리자 추가";
|
||||||
"lng_channel_admin_sure" = "{user}를 관리자로 추가하시겠습니까?";
|
"lng_channel_admin_sure" = "{user}를 관리자로 추가하시겠습니까?";
|
||||||
|
@ -564,10 +565,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_emoji_category1" = "사람";
|
"lng_emoji_category1" = "사람";
|
||||||
"lng_emoji_category2" = "자연";
|
"lng_emoji_category2" = "자연";
|
||||||
"lng_emoji_category3" = "음식점";
|
"lng_emoji_category3" = "음식점";
|
||||||
"lng_emoji_category4" = "기념일";
|
"lng_emoji_category4" = "활동";
|
||||||
"lng_emoji_category5" = "활동";
|
"lng_emoji_category5" = "여행 및 장소";
|
||||||
"lng_emoji_category6" = "여행 및 장소";
|
"lng_emoji_category6" = "물건";
|
||||||
"lng_emoji_category7" = "오브제 & 상징";
|
"lng_emoji_category7" = "심볼 및 국기";
|
||||||
|
|
||||||
"lng_switch_stickers" = "스티커";
|
"lng_switch_stickers" = "스티커";
|
||||||
"lng_switch_emoji" = "이모티콘";
|
"lng_switch_emoji" = "이모티콘";
|
||||||
|
@ -581,6 +582,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_not_found" = "스티커 팩을 찾을 수 없습니다.";
|
"lng_stickers_not_found" = "스티커 팩을 찾을 수 없습니다.";
|
||||||
"lng_stickers_copied" = "클립보드에 스티커 팩 링크가 복사 되었습니다.";
|
"lng_stickers_copied" = "클립보드에 스티커 팩 링크가 복사 되었습니다.";
|
||||||
"lng_stickers_default_set" = "Great Minds";
|
"lng_stickers_default_set" = "Great Minds";
|
||||||
|
"lng_stickers_you_have" = "스티커팩 관리 및 변경";
|
||||||
|
"lng_stickers_packs" = "스티커팩";
|
||||||
|
"lng_stickers_reorder" = "클릭과 드래그를 통하여 스태커 팩을 변경하세요";
|
||||||
|
"lng_stickers_remove" = "삭제";
|
||||||
|
"lng_stickers_return" = "실행취소";
|
||||||
|
"lng_stickers_restore" = "복구";
|
||||||
|
"lng_stickers_count" = "{count:Loading..|# 스티커|# 스티커} ";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "사진";
|
"lng_in_dlg_photo" = "사진";
|
||||||
"lng_in_dlg_video" = "비디오";
|
"lng_in_dlg_video" = "비디오";
|
||||||
|
@ -658,6 +666,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
"lng_choose_images" = "이미지 선택";
|
"lng_choose_images" = "이미지 선택";
|
||||||
|
|
||||||
|
"lng_context_view_profile" = "프로필 보기";
|
||||||
|
"lng_context_view_group" = "그룹 정보 보기";
|
||||||
|
"lng_context_view_channel" = "채널 정보 보기";
|
||||||
|
|
||||||
"lng_context_open_link" = "링크 열기";
|
"lng_context_open_link" = "링크 열기";
|
||||||
"lng_context_copy_link" = "링크 복사";
|
"lng_context_copy_link" = "링크 복사";
|
||||||
"lng_context_open_email" = "이 주소로 메시지 보내기";
|
"lng_context_open_email" = "이 주소로 메시지 보내기";
|
||||||
|
@ -789,7 +801,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
||||||
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
||||||
"lng_new_version_text" = "— 그룹방은 이름,로고, 초대등이 가능한 여러 관리자 설정 가능\n— 기존 200명까지 허용 가능한 그룹방은 슈퍼그룹방으로 업그레이드를 하여 1,000명까지 허용 가능\n\n관리자 및 슈퍼그룹방에 대하여:\n{link}";
|
"lng_new_version_text" = "— 스티커관리 : 스티커팩을 순서를 수동으로 변경하여, 연결된 모든 기기에 동기화 \n— 스티커를 지속하여 누를 경우 전송전 프리뷰 기능 추가\n— 채팅목록에 채팅관련 메뉴 추가\n— 기존 이모티콘 지원";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
||||||
|
|
||||||
|
|
|
@ -431,6 +431,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_channel_add_admins" = "Beheerder toevoegen";
|
"lng_channel_add_admins" = "Beheerder toevoegen";
|
||||||
"lng_channel_add_members" = "Deelnemers toevoegen";
|
"lng_channel_add_members" = "Deelnemers toevoegen";
|
||||||
"lng_channel_members" = "Deelnemers";
|
"lng_channel_members" = "Deelnemers";
|
||||||
|
"lng_channel_only_last_shown" = "De laatste {count:_not_used_|# deelnemer|# deelnemers} worden hier weergegeven";
|
||||||
"lng_channel_admins" = "Beheerders";
|
"lng_channel_admins" = "Beheerders";
|
||||||
"lng_channel_add_admin" = "Beheerder toevoegen";
|
"lng_channel_add_admin" = "Beheerder toevoegen";
|
||||||
"lng_channel_admin_sure" = "{user} aan beheerders toevoegen?";
|
"lng_channel_admin_sure" = "{user} aan beheerders toevoegen?";
|
||||||
|
@ -564,10 +565,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_emoji_category1" = "Mensen";
|
"lng_emoji_category1" = "Mensen";
|
||||||
"lng_emoji_category2" = "Natuur";
|
"lng_emoji_category2" = "Natuur";
|
||||||
"lng_emoji_category3" = "Eten & drinken";
|
"lng_emoji_category3" = "Eten & drinken";
|
||||||
"lng_emoji_category4" = "Feestelijkheid";
|
"lng_emoji_category4" = "Activiteit";
|
||||||
"lng_emoji_category5" = "Activiteit";
|
"lng_emoji_category5" = "Reizen & plekken";
|
||||||
"lng_emoji_category6" = "Reizen & plekken";
|
"lng_emoji_category6" = "Objecten";
|
||||||
"lng_emoji_category7" = "Objecten & symbolen";
|
"lng_emoji_category7" = "Symbolen en vlaggen";
|
||||||
|
|
||||||
"lng_switch_stickers" = "Stickers";
|
"lng_switch_stickers" = "Stickers";
|
||||||
"lng_switch_emoji" = "Emoji";
|
"lng_switch_emoji" = "Emoji";
|
||||||
|
@ -581,6 +582,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_not_found" = "Stickerbundel niet gevonden.";
|
"lng_stickers_not_found" = "Stickerbundel niet gevonden.";
|
||||||
"lng_stickers_copied" = "Stickerbundel-link gekopieerd naar klembord";
|
"lng_stickers_copied" = "Stickerbundel-link gekopieerd naar klembord";
|
||||||
"lng_stickers_default_set" = "Grote geesten";
|
"lng_stickers_default_set" = "Grote geesten";
|
||||||
|
"lng_stickers_you_have" = "Beheer en sorteer stickerbundels";
|
||||||
|
"lng_stickers_packs" = "Stickerbundels";
|
||||||
|
"lng_stickers_reorder" = "Klik en sleep om stickerbundels te herschikken";
|
||||||
|
"lng_stickers_remove" = "Verwijder";
|
||||||
|
"lng_stickers_return" = "Ongedaan maken";
|
||||||
|
"lng_stickers_restore" = "Herstellen";
|
||||||
|
"lng_stickers_count" = "{count:Laden..|# sticker|# stickers}";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "Foto";
|
"lng_in_dlg_photo" = "Foto";
|
||||||
"lng_in_dlg_video" = "Video";
|
"lng_in_dlg_video" = "Video";
|
||||||
|
@ -658,6 +666,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
"lng_choose_images" = "Afbeeldingen kiezen";
|
"lng_choose_images" = "Afbeeldingen kiezen";
|
||||||
|
|
||||||
|
"lng_context_view_profile" = "Profiel weergeven";
|
||||||
|
"lng_context_view_group" = "Groepsinformatie weergeven";
|
||||||
|
"lng_context_view_channel" = "Kanaalinformatie weergeven";
|
||||||
|
|
||||||
"lng_context_open_link" = "Link openen";
|
"lng_context_open_link" = "Link openen";
|
||||||
"lng_context_copy_link" = "Link kopiëren";
|
"lng_context_copy_link" = "Link kopiëren";
|
||||||
"lng_context_open_email" = "Naar dit adres sturen";
|
"lng_context_open_email" = "Naar dit adres sturen";
|
||||||
|
@ -789,7 +801,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
|
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
|
||||||
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
||||||
"lng_new_version_text" = "— Meerdere beheerders in groepen, naast het wijzigen van de groepsnaam en afbeelding kunnen beheerders ook leden toevoegen en verwijderen.\n— Groepen die de limiet van 200 deelnemers hebben bereikt kunnen worden opgewaardeerd naar supergroepen met maximaal 1000 deelnemers.\n\nMeer informatie over supergroepen en de andere nieuwe functies is hier te vinden: \n{link}";
|
"lng_new_version_text" = "— Stickerbeheer: Je kunt nu handmatig je stickerbundels sorteren, de volgorde synchroniseren we voor je, over al je apparaten.\n— Klik en hou een sticker vast om een voorbeeld weer te geven voor het versturen.\n— Nieuw contextmenu voor chats in het chats-overzicht\n— Ondersteuning voor alle bestaande emoji";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
||||||
|
|
||||||
|
|
|
@ -431,6 +431,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_channel_add_admins" = "Novo administrador";
|
"lng_channel_add_admins" = "Novo administrador";
|
||||||
"lng_channel_add_members" = "Adicionar membros";
|
"lng_channel_add_members" = "Adicionar membros";
|
||||||
"lng_channel_members" = "Membros";
|
"lng_channel_members" = "Membros";
|
||||||
|
"lng_channel_only_last_shown" = "Somente os últimos {count:_not_used_|# membro é|# membros são} exibidos";
|
||||||
"lng_channel_admins" = "Administradores";
|
"lng_channel_admins" = "Administradores";
|
||||||
"lng_channel_add_admin" = "Adicionar Administrador";
|
"lng_channel_add_admin" = "Adicionar Administrador";
|
||||||
"lng_channel_admin_sure" = "Adicionar {user} aos administradores?";
|
"lng_channel_admin_sure" = "Adicionar {user} aos administradores?";
|
||||||
|
@ -510,7 +511,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_reached" = "{count:_not_used_|# membro|# membros} limite alcançado";
|
"lng_profile_migrate_reached" = "{count:_not_used_|# membro|# membros} limite alcançado";
|
||||||
"lng_profile_migrate_about" = "Se você deseja ir além do limite, pode converter seu grupo em um supergrupo. Nos supergrupos:";
|
"lng_profile_migrate_about" = "Se você deseja ir além do limite, pode converter seu grupo em um supergrupo. Nos supergrupos:";
|
||||||
"lng_profile_migrate_feature1" = "— O limite de membros são {count:_not_used_|# usuário|# usuários}";
|
"lng_profile_migrate_feature1" = "— O limite de membros são {count:_not_used_|# usuário|# usuários}";
|
||||||
"lng_profile_migrate_feature2" = "— Novos membros podem ver o histórico completo do chat";
|
"lng_profile_migrate_feature2" = "— Novos membros podem ver todo o histórico";
|
||||||
"lng_profile_migrate_feature3" = "— Administradores podem apagar mensagens para todos";
|
"lng_profile_migrate_feature3" = "— Administradores podem apagar mensagens para todos";
|
||||||
"lng_profile_migrate_feature4" = "— Notificações silenciadas por padrão";
|
"lng_profile_migrate_feature4" = "— Notificações silenciadas por padrão";
|
||||||
"lng_profile_migrate_button" = "Atualizar para supergrupo";
|
"lng_profile_migrate_button" = "Atualizar para supergrupo";
|
||||||
|
@ -564,10 +565,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_emoji_category1" = "Pessoas";
|
"lng_emoji_category1" = "Pessoas";
|
||||||
"lng_emoji_category2" = "Natureza";
|
"lng_emoji_category2" = "Natureza";
|
||||||
"lng_emoji_category3" = "Comidas e Bebidas";
|
"lng_emoji_category3" = "Comidas e Bebidas";
|
||||||
"lng_emoji_category4" = "Celebração";
|
"lng_emoji_category4" = "Atividade";
|
||||||
"lng_emoji_category5" = "Atividade";
|
"lng_emoji_category5" = "Viagens e Lugares";
|
||||||
"lng_emoji_category6" = "Viagens e Lugares";
|
"lng_emoji_category6" = "Objetos";
|
||||||
"lng_emoji_category7" = "Objetos e Símbolos";
|
"lng_emoji_category7" = "Símbolos e Bandeiras";
|
||||||
|
|
||||||
"lng_switch_stickers" = "Stickers";
|
"lng_switch_stickers" = "Stickers";
|
||||||
"lng_switch_emoji" = "Emoji";
|
"lng_switch_emoji" = "Emoji";
|
||||||
|
@ -581,6 +582,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_not_found" = "Pacote de sticker não encontrado.";
|
"lng_stickers_not_found" = "Pacote de sticker não encontrado.";
|
||||||
"lng_stickers_copied" = "Link copiado para a área de transferência.";
|
"lng_stickers_copied" = "Link copiado para a área de transferência.";
|
||||||
"lng_stickers_default_set" = "Grandes Mentes";
|
"lng_stickers_default_set" = "Grandes Mentes";
|
||||||
|
"lng_stickers_you_have" = "Gerenciar e reordenar os pacotes de sticker";
|
||||||
|
"lng_stickers_packs" = "Pacotes de Sticker";
|
||||||
|
"lng_stickers_reorder" = "Clique e arraste para reordenar os pacotes";
|
||||||
|
"lng_stickers_remove" = "Remover";
|
||||||
|
"lng_stickers_return" = "Desfazer";
|
||||||
|
"lng_stickers_restore" = "Restaurar";
|
||||||
|
"lng_stickers_count" = "{count:Carregando..|# sticker|# stickers}";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "Foto";
|
"lng_in_dlg_photo" = "Foto";
|
||||||
"lng_in_dlg_video" = "Vídeo";
|
"lng_in_dlg_video" = "Vídeo";
|
||||||
|
@ -658,6 +666,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
"lng_choose_images" = "Escolher imagens";
|
"lng_choose_images" = "Escolher imagens";
|
||||||
|
|
||||||
|
"lng_context_view_profile" = "Ver perfil";
|
||||||
|
"lng_context_view_group" = "Ver info do grupo";
|
||||||
|
"lng_context_view_channel" = "Ver info do canal";
|
||||||
|
|
||||||
"lng_context_open_link" = "Abrir Link";
|
"lng_context_open_link" = "Abrir Link";
|
||||||
"lng_context_copy_link" = "Copiar Link";
|
"lng_context_copy_link" = "Copiar Link";
|
||||||
"lng_context_open_email" = "Escrever para este endereço";
|
"lng_context_open_email" = "Escrever para este endereço";
|
||||||
|
@ -789,7 +801,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
|
||||||
"lng_new_version_minor" = "— Resolução de bugs e outras melhorias menores";
|
"lng_new_version_minor" = "— Resolução de bugs e outras melhorias menores";
|
||||||
"lng_new_version_text" = "— Grupos agora podem ter múltiplos administradores com a habilidade de editar o nome e o logo, além de adicionar e remover membros\n— Grupos que ultrapassarem o limite dos 200 usuários poderão atualizar para supergrupos e ter até 1.000 membros\n\nMais sobre administradores e supergrupos:\n{link}";
|
"lng_new_version_text" = "— Gerenciamento de stickers: rearranje manualmente seus pacotes de sticker, a ordem dos pacotes agora é sincronizada entre todos os dispositivos\n— Clique e segure sobre um sticker para pré-visualizar antes de enviar\n— Novo menu de contexto para os chats na lista de chats \n— Suporte para todos os emojis existentes";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "gui/filedialog.h"
|
#include "gui/filedialog.h"
|
||||||
|
|
||||||
BackgroundWidget::BackgroundWidget(QWidget *parent, LayeredWidget *w) : QWidget(parent), w(w),
|
BackgroundWidget::BackgroundWidget(QWidget *parent, LayeredWidget *w) : TWidget(parent)
|
||||||
aBackground(0), aBackgroundFunc(anim::easeOutCirc), hiding(false), shadow(st::boxShadow) {
|
, w(w)
|
||||||
|
, aBackground(0)
|
||||||
|
, aBackgroundFunc(anim::easeOutCirc)
|
||||||
|
, hiding(false)
|
||||||
|
, shadow(st::boxShadow) {
|
||||||
w->setParent(this);
|
w->setParent(this);
|
||||||
if (App::app()) App::app()->mtpPause();
|
if (App::app()) App::app()->mtpPause();
|
||||||
setGeometry(0, 0, App::wnd()->width(), App::wnd()->height());
|
setGeometry(0, 0, App::wnd()->width(), App::wnd()->height());
|
||||||
|
@ -189,3 +193,115 @@ BackgroundWidget::~BackgroundWidget() {
|
||||||
(*i)->deleteLater();
|
(*i)->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StickerPreviewWidget::StickerPreviewWidget(QWidget *parent) : TWidget(parent)
|
||||||
|
, a_shown(0, 0)
|
||||||
|
, _a_shown(animFunc(this, &StickerPreviewWidget::animStep_shown))
|
||||||
|
, _doc(0)
|
||||||
|
, _cacheStatus(CacheNotLoaded) {
|
||||||
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerPreviewWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
QRect r(e->rect());
|
||||||
|
|
||||||
|
const QPixmap &draw(currentImage());
|
||||||
|
uint32 w = draw.width() / cIntRetinaFactor(), h = draw.height() / cIntRetinaFactor();
|
||||||
|
if (_a_shown.animating()) {
|
||||||
|
float64 shown = a_shown.current();
|
||||||
|
p.setOpacity(shown);
|
||||||
|
// w = qMax(qRound(w * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(w % 2), 1);
|
||||||
|
// h = qMax(qRound(h * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(h % 2), 1);
|
||||||
|
}
|
||||||
|
p.fillRect(r, st::stickerPreviewBg);
|
||||||
|
p.drawPixmap((width() - w) / 2, (height() - h) / 2, draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerPreviewWidget::resizeEvent(QResizeEvent *e) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StickerPreviewWidget::animStep_shown(float64 ms) {
|
||||||
|
float64 dt = ms / st::stickerPreviewDuration;
|
||||||
|
if (dt >= 1) {
|
||||||
|
a_shown.finish();
|
||||||
|
_a_shown.stop();
|
||||||
|
if (a_shown.current() < 0.5) hide();
|
||||||
|
} else {
|
||||||
|
a_shown.update(dt, anim::linear);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerPreviewWidget::showPreview(DocumentData *sticker) {
|
||||||
|
if (sticker && !sticker->sticker()) sticker = 0;
|
||||||
|
if (sticker) {
|
||||||
|
_cache = QPixmap();
|
||||||
|
if (isHidden() || _a_shown.animating()) {
|
||||||
|
if (isHidden()) show();
|
||||||
|
a_shown.start(1);
|
||||||
|
_a_shown.start();
|
||||||
|
} else {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
} else if (isHidden()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
a_shown.start(0);
|
||||||
|
_a_shown.start();
|
||||||
|
}
|
||||||
|
_doc = sticker;
|
||||||
|
_cacheStatus = CacheNotLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerPreviewWidget::hidePreview() {
|
||||||
|
showPreview(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize StickerPreviewWidget::currentDimensions() const {
|
||||||
|
if (!_doc) return QSize(_cache.width() / cIntRetinaFactor(), _cache.height() / cIntRetinaFactor());
|
||||||
|
|
||||||
|
QSize result(qMax(_doc->dimensions.width(), 1), qMax(_doc->dimensions.height(), 1));
|
||||||
|
if (result.width() > st::maxStickerSize) {
|
||||||
|
result.setHeight(qMax(qRound((st::maxStickerSize * result.height()) / result.width()), 1));
|
||||||
|
result.setWidth(st::maxStickerSize);
|
||||||
|
}
|
||||||
|
if (result.height() > st::maxStickerSize) {
|
||||||
|
result.setWidth(qMax(qRound((st::maxStickerSize * result.width()) / result.height()), 1));
|
||||||
|
result.setHeight(st::maxStickerSize);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap StickerPreviewWidget::currentImage() const {
|
||||||
|
if (_doc && _cacheStatus != CacheLoaded) {
|
||||||
|
bool already = !_doc->already().isEmpty(), hasdata = !_doc->data.isEmpty();
|
||||||
|
if (!_doc->loader && _doc->status != FileFailed && !already && !hasdata) {
|
||||||
|
_doc->save(QString());
|
||||||
|
}
|
||||||
|
if (_doc->sticker()->img->isNull() && (already || hasdata)) {
|
||||||
|
if (already) {
|
||||||
|
_doc->sticker()->img = ImagePtr(_doc->already());
|
||||||
|
} else {
|
||||||
|
_doc->sticker()->img = ImagePtr(_doc->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_doc->sticker()->img->isNull()) {
|
||||||
|
if (_cacheStatus != CacheThumbLoaded) {
|
||||||
|
QSize s = currentDimensions();
|
||||||
|
_cache = _doc->thumb->pixBlurred(s.width(), s.height());
|
||||||
|
_cacheStatus = CacheThumbLoaded;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QSize s = currentDimensions();
|
||||||
|
_cache = _doc->sticker()->img->pix(s.width(), s.height());
|
||||||
|
_cacheStatus = CacheLoaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
StickerPreviewWidget::~StickerPreviewWidget() {
|
||||||
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ signals:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BackgroundWidget : public QWidget, public Animated {
|
class BackgroundWidget : public TWidget, public Animated {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -104,3 +104,39 @@ private:
|
||||||
|
|
||||||
BoxShadow shadow;
|
BoxShadow shadow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StickerPreviewWidget : public TWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
StickerPreviewWidget(QWidget *parent);
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
bool animStep_shown(float64 ms);
|
||||||
|
|
||||||
|
void showPreview(DocumentData *sticker);
|
||||||
|
void hidePreview();
|
||||||
|
|
||||||
|
~StickerPreviewWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QSize currentDimensions() const;
|
||||||
|
QPixmap currentImage() const;
|
||||||
|
|
||||||
|
anim::fvalue a_shown;
|
||||||
|
Animation _a_shown;
|
||||||
|
DocumentData *_doc;
|
||||||
|
|
||||||
|
enum CacheStatus {
|
||||||
|
CacheNotLoaded,
|
||||||
|
CacheThumbLoaded,
|
||||||
|
CacheLoaded,
|
||||||
|
};
|
||||||
|
mutable CacheStatus _cacheStatus;
|
||||||
|
mutable QPixmap _cache;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -579,11 +579,23 @@ namespace {
|
||||||
}
|
}
|
||||||
quint32 size = 0;
|
quint32 size = 0;
|
||||||
for (FileLocations::const_iterator i = _fileLocations.cbegin(), e = _fileLocations.cend(); i != e; ++i) {
|
for (FileLocations::const_iterator i = _fileLocations.cbegin(), e = _fileLocations.cend(); i != e; ++i) {
|
||||||
// location + type + namelen + name + date + size
|
// location + type + namelen + name
|
||||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(i.value().name) + _dateTimeSize() + sizeof(quint32);
|
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(i.value().name());
|
||||||
|
if (AppVersion > 9013) {
|
||||||
|
// bookmark
|
||||||
|
size += _bytearraySize(i.value().bookmark());
|
||||||
}
|
}
|
||||||
|
// date + size
|
||||||
|
size += _dateTimeSize() + sizeof(quint32);
|
||||||
|
}
|
||||||
|
|
||||||
//end mark
|
//end mark
|
||||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(QString()) + _dateTimeSize() + sizeof(quint32);
|
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(QString());
|
||||||
|
if (AppVersion > 9013) {
|
||||||
|
size += _bytearraySize(QByteArray());
|
||||||
|
}
|
||||||
|
size += _dateTimeSize() + sizeof(quint32);
|
||||||
|
|
||||||
size += sizeof(quint32); // aliases count
|
size += sizeof(quint32); // aliases count
|
||||||
for (FileLocationAliases::const_iterator i = _fileLocationAliases.cbegin(), e = _fileLocationAliases.cend(); i != e; ++i) {
|
for (FileLocationAliases::const_iterator i = _fileLocationAliases.cbegin(), e = _fileLocationAliases.cend(); i != e; ++i) {
|
||||||
// alias + location
|
// alias + location
|
||||||
|
@ -592,9 +604,19 @@ namespace {
|
||||||
|
|
||||||
EncryptedDescriptor data(size);
|
EncryptedDescriptor data(size);
|
||||||
for (FileLocations::const_iterator i = _fileLocations.cbegin(); i != _fileLocations.cend(); ++i) {
|
for (FileLocations::const_iterator i = _fileLocations.cbegin(); i != _fileLocations.cend(); ++i) {
|
||||||
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint32(i.value().type) << i.value().name << i.value().modified << quint32(i.value().size);
|
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint32(i.value().type) << i.value().name();
|
||||||
|
if (AppVersion > 9013) {
|
||||||
|
data.stream << i.value().bookmark();
|
||||||
}
|
}
|
||||||
data.stream << quint64(0) << quint64(0) << quint32(0) << QString() << QDateTime::currentDateTime() << quint32(0);
|
data.stream << i.value().modified << quint32(i.value().size);
|
||||||
|
}
|
||||||
|
|
||||||
|
data.stream << quint64(0) << quint64(0) << quint32(0) << QString();
|
||||||
|
if (AppVersion > 9013) {
|
||||||
|
data.stream << QByteArray();
|
||||||
|
}
|
||||||
|
data.stream << QDateTime::currentDateTime() << quint32(0);
|
||||||
|
|
||||||
data.stream << quint32(_fileLocationAliases.size());
|
data.stream << quint32(_fileLocationAliases.size());
|
||||||
for (FileLocationAliases::const_iterator i = _fileLocationAliases.cbegin(), e = _fileLocationAliases.cend(); i != e; ++i) {
|
for (FileLocationAliases::const_iterator i = _fileLocationAliases.cbegin(), e = _fileLocationAliases.cend(); i != e; ++i) {
|
||||||
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint64(i.value().first) << quint64(i.value().second);
|
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint64(i.value().first) << quint64(i.value().second);
|
||||||
|
@ -617,11 +639,17 @@ namespace {
|
||||||
bool endMarkFound = false;
|
bool endMarkFound = false;
|
||||||
while (!locations.stream.atEnd()) {
|
while (!locations.stream.atEnd()) {
|
||||||
quint64 first, second;
|
quint64 first, second;
|
||||||
|
QByteArray bookmark;
|
||||||
FileLocation loc;
|
FileLocation loc;
|
||||||
quint32 type;
|
quint32 type;
|
||||||
locations.stream >> first >> second >> type >> loc.name >> loc.modified >> loc.size;
|
locations.stream >> first >> second >> type >> loc.fname;
|
||||||
|
if (locations.version > 9013) {
|
||||||
|
locations.stream >> bookmark;
|
||||||
|
}
|
||||||
|
locations.stream >> loc.modified >> loc.size;
|
||||||
|
loc.setBookmark(bookmark);
|
||||||
|
|
||||||
if (!first && !second && !type && loc.name.isEmpty() && !loc.size) { // end mark
|
if (!first && !second && !type && loc.fname.isEmpty() && !loc.size) { // end mark
|
||||||
endMarkFound = true;
|
endMarkFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -629,12 +657,8 @@ namespace {
|
||||||
MediaKey key(first, second);
|
MediaKey key(first, second);
|
||||||
loc.type = StorageFileType(type);
|
loc.type = StorageFileType(type);
|
||||||
|
|
||||||
if (loc.check()) {
|
|
||||||
_fileLocations.insert(key, loc);
|
_fileLocations.insert(key, loc);
|
||||||
_fileLocationPairs.insert(loc.name, FileLocationPair(key, loc));
|
_fileLocationPairs.insert(loc.fname, FileLocationPair(key, loc));
|
||||||
} else {
|
|
||||||
_writeLocations();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endMarkFound) {
|
if (endMarkFound) {
|
||||||
|
@ -1038,12 +1062,26 @@ namespace {
|
||||||
cSetAskDownloadPath(v == 1);
|
cSetAskDownloadPath(v == 1);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dbiDownloadPath: {
|
case dbiDownloadPathOld: {
|
||||||
QString v;
|
QString v;
|
||||||
stream >> v;
|
stream >> v;
|
||||||
if (!_checkStreamStatus(stream)) return false;
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
|
if (!v.isEmpty() && v != qstr("tmp") && !v.endsWith('/')) v += '/';
|
||||||
cSetDownloadPath(v);
|
cSetDownloadPath(v);
|
||||||
|
cSetDownloadPathBookmark(QByteArray());
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case dbiDownloadPath: {
|
||||||
|
QString v;
|
||||||
|
QByteArray bookmark;
|
||||||
|
stream >> v >> bookmark;
|
||||||
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
|
if (!v.isEmpty() && v != qstr("tmp") && !v.endsWith('/')) v += '/';
|
||||||
|
cSetDownloadPath(v);
|
||||||
|
cSetDownloadPathBookmark(bookmark);
|
||||||
|
psDownloadPathEnableAccess();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dbiCompressPastedImage: {
|
case dbiCompressPastedImage: {
|
||||||
|
@ -1054,22 +1092,12 @@ namespace {
|
||||||
cSetCompressPastedImage(v == 1);
|
cSetCompressPastedImage(v == 1);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dbiEmojiTab: {
|
case dbiEmojiTabOld: {
|
||||||
qint32 v;
|
qint32 v;
|
||||||
stream >> v;
|
stream >> v;
|
||||||
if (!_checkStreamStatus(stream)) return false;
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
switch (v) {
|
// deprecated
|
||||||
case dbietRecent : cSetEmojiTab(dbietRecent ); break;
|
|
||||||
case dbietPeople : cSetEmojiTab(dbietPeople ); break;
|
|
||||||
case dbietNature : cSetEmojiTab(dbietNature ); break;
|
|
||||||
case dbietFood : cSetEmojiTab(dbietFood ); break;
|
|
||||||
case dbietCelebration: cSetEmojiTab(dbietCelebration); break;
|
|
||||||
case dbietActivity : cSetEmojiTab(dbietActivity ); break;
|
|
||||||
case dbietTravel : cSetEmojiTab(dbietTravel ); break;
|
|
||||||
case dbietObjects : cSetEmojiTab(dbietObjects ); break;
|
|
||||||
case dbietStickers : cSetEmojiTab(dbietStickers ); break;
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dbiRecentEmojisOld: {
|
case dbiRecentEmojisOld: {
|
||||||
|
@ -1362,7 +1390,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 size = 14 * (sizeof(quint32) + sizeof(qint32));
|
uint32 size = 14 * (sizeof(quint32) + sizeof(qint32));
|
||||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath());
|
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath()) + _bytearraySize(cAskDownloadPath() ? QByteArray() : cDownloadPathBookmark());
|
||||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||||
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
||||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||||
|
@ -1380,9 +1408,8 @@ namespace {
|
||||||
data.stream << quint32(dbiNotifyView) << qint32(cNotifyView());
|
data.stream << quint32(dbiNotifyView) << qint32(cNotifyView());
|
||||||
data.stream << quint32(dbiWindowsNotifications) << qint32(cWindowsNotifications());
|
data.stream << quint32(dbiWindowsNotifications) << qint32(cWindowsNotifications());
|
||||||
data.stream << quint32(dbiAskDownloadPath) << qint32(cAskDownloadPath());
|
data.stream << quint32(dbiAskDownloadPath) << qint32(cAskDownloadPath());
|
||||||
data.stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath());
|
data.stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath()) << (cAskDownloadPath() ? QByteArray() : cDownloadPathBookmark());
|
||||||
data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage());
|
data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage());
|
||||||
data.stream << quint32(dbiEmojiTab) << qint32(cEmojiTab());
|
|
||||||
data.stream << quint32(dbiDialogLastPath) << cDialogLastPath();
|
data.stream << quint32(dbiDialogLastPath) << cDialogLastPath();
|
||||||
data.stream << quint32(dbiSongVolume) << qint32(qRound(cSongVolume() * 1e6));
|
data.stream << quint32(dbiSongVolume) << qint32(qRound(cSongVolume() * 1e6));
|
||||||
|
|
||||||
|
@ -2178,14 +2205,14 @@ namespace Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeFileLocation(MediaKey location, const FileLocation &local) {
|
void writeFileLocation(MediaKey location, const FileLocation &local) {
|
||||||
if (local.name.isEmpty()) return;
|
if (local.fname.isEmpty()) return;
|
||||||
|
|
||||||
FileLocationAliases::const_iterator aliasIt = _fileLocationAliases.constFind(location);
|
FileLocationAliases::const_iterator aliasIt = _fileLocationAliases.constFind(location);
|
||||||
if (aliasIt != _fileLocationAliases.cend()) {
|
if (aliasIt != _fileLocationAliases.cend()) {
|
||||||
location = aliasIt.value();
|
location = aliasIt.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileLocationPairs::iterator i = _fileLocationPairs.find(local.name);
|
FileLocationPairs::iterator i = _fileLocationPairs.find(local.fname);
|
||||||
if (i != _fileLocationPairs.cend()) {
|
if (i != _fileLocationPairs.cend()) {
|
||||||
if (i.value().second == local) {
|
if (i.value().second == local) {
|
||||||
if (i.value().first != location) {
|
if (i.value().first != location) {
|
||||||
|
@ -2205,7 +2232,7 @@ namespace Local {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_fileLocations.insert(location, local);
|
_fileLocations.insert(location, local);
|
||||||
_fileLocationPairs.insert(local.name, FileLocationPair(location, local));
|
_fileLocationPairs.insert(local.fname, FileLocationPair(location, local));
|
||||||
_writeLocations(WriteMapFast);
|
_writeLocations(WriteMapFast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2218,9 +2245,8 @@ namespace Local {
|
||||||
FileLocations::iterator i = _fileLocations.find(location);
|
FileLocations::iterator i = _fileLocations.find(location);
|
||||||
for (FileLocations::iterator i = _fileLocations.find(location); (i != _fileLocations.end()) && (i.key() == location);) {
|
for (FileLocations::iterator i = _fileLocations.find(location); (i != _fileLocations.end()) && (i.key() == location);) {
|
||||||
if (check) {
|
if (check) {
|
||||||
QFileInfo info(i.value().name);
|
if (!i.value().check()) {
|
||||||
if (!info.exists() || info.lastModified() != i.value().modified || info.size() != i.value().size) {
|
_fileLocationPairs.remove(i.value().fname);
|
||||||
_fileLocationPairs.remove(i.value().name);
|
|
||||||
i = _fileLocations.erase(i);
|
i = _fileLocations.erase(i);
|
||||||
_writeLocations();
|
_writeLocations();
|
||||||
continue;
|
continue;
|
||||||
|
@ -2441,7 +2467,7 @@ namespace Local {
|
||||||
|
|
||||||
TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader) {
|
TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader) {
|
||||||
StorageMap::iterator j = _stickerImagesMap.find(location);
|
StorageMap::iterator j = _stickerImagesMap.find(location);
|
||||||
if (j == _stickerImagesMap.cend()) {
|
if (j == _stickerImagesMap.cend() || !_localLoader) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return _localLoader->addTask(new StickerImageLoadTask(j->first, location, loader));
|
return _localLoader->addTask(new StickerImageLoadTask(j->first, location, loader));
|
||||||
|
@ -2500,7 +2526,7 @@ namespace Local {
|
||||||
|
|
||||||
TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader) {
|
TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader) {
|
||||||
StorageMap::iterator j = _audiosMap.find(location);
|
StorageMap::iterator j = _audiosMap.find(location);
|
||||||
if (j == _audiosMap.cend()) {
|
if (j == _audiosMap.cend() || !_localLoader) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return _localLoader->addTask(new AudioLoadTask(j->first, location, loader));
|
return _localLoader->addTask(new AudioLoadTask(j->first, location, loader));
|
||||||
|
@ -2582,11 +2608,12 @@ namespace Local {
|
||||||
_writeMap();
|
_writeMap();
|
||||||
} else {
|
} else {
|
||||||
int32 setsCount = 0;
|
int32 setsCount = 0;
|
||||||
quint32 size = sizeof(quint32) + _bytearraySize(cStickersHash());
|
QByteArray hashToWrite = (qsl("%d:") + QString::number(cStickersHash())).toUtf8();
|
||||||
|
quint32 size = sizeof(quint32) + _bytearraySize(hashToWrite);
|
||||||
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) {
|
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) {
|
||||||
bool notLoaded = (i->flags & MTPDstickerSet_flag_NOT_LOADED);
|
bool notLoaded = (i->flags & MTPDstickerSet_flag_NOT_LOADED);
|
||||||
if (notLoaded) {
|
if (notLoaded) {
|
||||||
if (!(i->flags & MTPDstickerSet::flag_disabled)) { // waiting to receive
|
if (!(i->flags & MTPDstickerSet::flag_disabled) || (i->flags & MTPDstickerSet::flag_official)) { // waiting to receive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2613,7 +2640,7 @@ namespace Local {
|
||||||
_writeMap(WriteMapFast);
|
_writeMap(WriteMapFast);
|
||||||
}
|
}
|
||||||
EncryptedDescriptor data(size);
|
EncryptedDescriptor data(size);
|
||||||
data.stream << quint32(setsCount) << cStickersHash();
|
data.stream << quint32(setsCount) << hashToWrite;
|
||||||
_writeStickerSet(data.stream, CustomStickerSetId);
|
_writeStickerSet(data.stream, CustomStickerSetId);
|
||||||
for (StickerSetsOrder::const_iterator i = cStickerSetsOrder().cbegin(), e = cStickerSetsOrder().cend(); i != e; ++i) {
|
for (StickerSetsOrder::const_iterator i = cStickerSetsOrder().cbegin(), e = cStickerSetsOrder().cend(); i != e; ++i) {
|
||||||
_writeStickerSet(data.stream, *i);
|
_writeStickerSet(data.stream, *i);
|
||||||
|
@ -2643,7 +2670,7 @@ namespace Local {
|
||||||
RecentStickerPack &recent(cRefRecentStickers());
|
RecentStickerPack &recent(cRefRecentStickers());
|
||||||
recent.clear();
|
recent.clear();
|
||||||
|
|
||||||
cSetStickersHash(QByteArray());
|
cSetStickersHash(0);
|
||||||
|
|
||||||
StickerSet &def(sets.insert(DefaultStickerSetId, StickerSet(DefaultStickerSetId, 0, lang(lng_stickers_default_set), QString(), 0, 0, MTPDstickerSet::flag_official)).value());
|
StickerSet &def(sets.insert(DefaultStickerSetId, StickerSet(DefaultStickerSetId, 0, lang(lng_stickers_default_set), QString(), 0, 0, MTPDstickerSet::flag_official)).value());
|
||||||
StickerSet &custom(sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0)).value());
|
StickerSet &custom(sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0)).value());
|
||||||
|
@ -2801,7 +2828,11 @@ namespace Local {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cSetStickersHash(hash);
|
if (hash.startsWith(qsl("%d:").toUtf8())) {
|
||||||
|
cSetStickersHash(QString::fromUtf8(hash.mid(3)).toInt());
|
||||||
|
} else {
|
||||||
|
cSetStickersHash(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeBackground(int32 id, const QImage &img) {
|
void writeBackground(int32 id, const QImage &img) {
|
||||||
|
|
|
@ -183,25 +183,63 @@ void logsInit() {
|
||||||
static _StreamCreator streamCreator;
|
static _StreamCreator streamCreator;
|
||||||
if (mainLogStream) return;
|
if (mainLogStream) return;
|
||||||
|
|
||||||
|
QFile beta(cExeDir() + qsl("TelegramBeta_data/tdata/beta"));
|
||||||
|
if (cBetaVersion()) {
|
||||||
|
cForceWorkingDir(cExeDir() + qsl("TelegramBeta_data/"));
|
||||||
|
if (*BetaPrivateKey) {
|
||||||
|
cSetBetaPrivateKey(QByteArray(BetaPrivateKey));
|
||||||
|
}
|
||||||
|
if (beta.open(QIODevice::WriteOnly)) {
|
||||||
|
QDataStream dataStream(&beta);
|
||||||
|
dataStream.setVersion(QDataStream::Qt_5_3);
|
||||||
|
dataStream << quint64(cRealBetaVersion()) << cBetaPrivateKey();
|
||||||
|
} else {
|
||||||
|
LOG(("Error: could not open \"beta\" file for writing private key!"));
|
||||||
|
}
|
||||||
|
} else if (beta.exists()) {
|
||||||
|
if (beta.open(QIODevice::ReadOnly)) {
|
||||||
|
QDataStream dataStream(&beta);
|
||||||
|
dataStream.setVersion(QDataStream::Qt_5_3);
|
||||||
|
|
||||||
|
quint64 v;
|
||||||
|
QByteArray k;
|
||||||
|
dataStream >> v >> k;
|
||||||
|
if (dataStream.status() == QDataStream::Ok) {
|
||||||
|
cSetBetaVersion(qMax(v, AppVersion * 1000ULL));
|
||||||
|
cSetBetaPrivateKey(k);
|
||||||
|
cSetRealBetaVersion(v);
|
||||||
|
|
||||||
|
cForceWorkingDir(cExeDir() + qsl("TelegramBeta_data/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cBetaVersion()) {
|
||||||
|
cSetDebug(true);
|
||||||
|
} else {
|
||||||
QString wasDir = cWorkingDir();
|
QString wasDir = cWorkingDir();
|
||||||
#if (defined Q_OS_MAC || defined Q_OS_LINUX)
|
#if (defined Q_OS_MAC || defined Q_OS_LINUX)
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
cForceWorkingDir(cExeDir());
|
cForceWorkingDir(cExeDir());
|
||||||
#else
|
#else
|
||||||
|
if(cWorkingDir().isEmpty()){
|
||||||
cForceWorkingDir(psAppDataPath());
|
cForceWorkingDir(psAppDataPath());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined Q_OS_LINUX && !defined _DEBUG) // fix first version
|
#if (defined Q_OS_LINUX && !defined _DEBUG) // fix first version
|
||||||
moveOldDataFiles(wasDir);
|
moveOldDataFiles(wasDir);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QString rightDir = cWorkingDir();
|
QString rightDir = cWorkingDir();
|
||||||
cForceWorkingDir(rightDir);
|
cForceWorkingDir(rightDir);
|
||||||
mainLog.setFileName(cWorkingDir() + "log.txt");
|
mainLog.setFileName(cWorkingDir() + "log.txt");
|
||||||
mainLog.open(QIODevice::WriteOnly | QIODevice::Text);
|
mainLog.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
if (!mainLog.isOpen()) {
|
if (!cBetaVersion() && !mainLog.isOpen()) {
|
||||||
cForceWorkingDir(cExeDir());
|
cForceWorkingDir(cExeDir());
|
||||||
mainLog.setFileName(cWorkingDir() + "log.txt");
|
mainLog.setFileName(cWorkingDir() + "log.txt");
|
||||||
mainLog.open(QIODevice::WriteOnly | QIODevice::Text);
|
mainLog.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
|
@ -224,18 +262,23 @@ void logsInit() {
|
||||||
cSetTestMode(true);
|
cSetTestMode(true);
|
||||||
LOG(("Switched to test mode!"));
|
LOG(("Switched to test mode!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (cWorkingDir() == psAppDataPath()) { // fix old "Telegram Win (Unofficial)" version
|
if (cWorkingDir() == psAppDataPath()) { // fix old "Telegram Win (Unofficial)" version
|
||||||
moveOldDataFiles(psAppDataPathOld());
|
moveOldDataFiles(psAppDataPathOld());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cDebug()) {
|
if (cDebug()) {
|
||||||
logsInitDebug();
|
logsInitDebug();
|
||||||
} else if (QFile(cWorkingDir() + qsl("tdata/withdebug")).exists()) {
|
} else if (QFile(cWorkingDir() + qsl("tdata/withdebug")).exists()) {
|
||||||
logsInitDebug();
|
logsInitDebug();
|
||||||
cSetDebug(true);
|
cSetDebug(true);
|
||||||
}
|
}
|
||||||
if (!cDevVersion() && QFile(cWorkingDir() + qsl("tdata/devversion")).exists()) {
|
|
||||||
|
if (cBetaVersion()) {
|
||||||
|
cSetDevVersion(false);
|
||||||
|
} else if (!cDevVersion() && QFile(cWorkingDir() + qsl("tdata/devversion")).exists()) {
|
||||||
cSetDevVersion(true);
|
cSetDevVersion(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
if (cRestartingUpdate()) {
|
if (cRestartingUpdate()) {
|
||||||
if (DevVersion) {
|
if (!cBetaVersion() && DevVersion) {
|
||||||
LOG(("Writing 'devversion' file before launching the Updater!"));
|
LOG(("Writing 'devversion' file before launching the Updater!"));
|
||||||
QFile f(cWorkingDir() + qsl("tdata/devversion"));
|
QFile f(cWorkingDir() + qsl("tdata/devversion"));
|
||||||
if (!f.exists() && f.open(QIODevice::WriteOnly)) {
|
if (!f.exists() && f.open(QIODevice::WriteOnly)) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "boxes/confirmbox.h"
|
#include "boxes/confirmbox.h"
|
||||||
#include "boxes/stickersetbox.h"
|
#include "boxes/stickersetbox.h"
|
||||||
#include "boxes/contactsbox.h"
|
#include "boxes/contactsbox.h"
|
||||||
|
#include "boxes/downloadpathbox.h"
|
||||||
|
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
|
@ -394,6 +395,7 @@ MainWidget::MainWidget(Window *window) : TWidget(window)
|
||||||
, _hider(0)
|
, _hider(0)
|
||||||
, _peerInStack(0)
|
, _peerInStack(0)
|
||||||
, _msgIdInStack(0)
|
, _msgIdInStack(0)
|
||||||
|
, _stickerPreview(0)
|
||||||
, _playerHeight(0)
|
, _playerHeight(0)
|
||||||
, _contentScrollAddToY(0)
|
, _contentScrollAddToY(0)
|
||||||
, _mediaType(this)
|
, _mediaType(this)
|
||||||
|
@ -743,6 +745,20 @@ QPixmap MainWidget::grabTopBar() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::ui_showStickerPreview(DocumentData *sticker) {
|
||||||
|
if (!sticker || !sticker->sticker()) return;
|
||||||
|
if (!_stickerPreview) {
|
||||||
|
_stickerPreview = new StickerPreviewWidget(this);
|
||||||
|
resizeEvent(0);
|
||||||
|
}
|
||||||
|
_stickerPreview->showPreview(sticker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::ui_hideStickerPreview() {
|
||||||
|
if (!_stickerPreview) return;
|
||||||
|
_stickerPreview->hidePreview();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::noHider(HistoryHider *destroyed) {
|
void MainWidget::noHider(HistoryHider *destroyed) {
|
||||||
if (_hider == destroyed) {
|
if (_hider == destroyed) {
|
||||||
_hider = 0;
|
_hider = 0;
|
||||||
|
@ -970,11 +986,17 @@ void MainWidget::addParticipants(PeerData *chatOrChannel, const QVector<UserData
|
||||||
}
|
}
|
||||||
} else if (chatOrChannel->isChannel()) {
|
} else if (chatOrChannel->isChannel()) {
|
||||||
QVector<MTPInputUser> inputUsers;
|
QVector<MTPInputUser> inputUsers;
|
||||||
inputUsers.reserve(users.size());
|
inputUsers.reserve(qMin(users.size(), int(MaxUsersPerInvite)));
|
||||||
for (QVector<UserData*>::const_iterator i = users.cbegin(), e = users.cend(); i != e; ++i) {
|
for (QVector<UserData*>::const_iterator i = users.cbegin(), e = users.cend(); i != e; ++i) {
|
||||||
inputUsers.push_back((*i)->inputUser);
|
inputUsers.push_back((*i)->inputUser);
|
||||||
}
|
if (inputUsers.size() == MaxUsersPerInvite) {
|
||||||
MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector<MTPInputUser>(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5);
|
MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector<MTPInputUser>(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5);
|
||||||
|
inputUsers.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inputUsers.isEmpty()) {
|
||||||
|
MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector<MTPInputUser>(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1585,6 +1607,7 @@ void MainWidget::messagesAffected(PeerData *peer, const MTPmessages_AffectedMess
|
||||||
void MainWidget::videoLoadProgress(mtpFileLoader *loader) {
|
void MainWidget::videoLoadProgress(mtpFileLoader *loader) {
|
||||||
VideoData *video = App::video(loader->objId());
|
VideoData *video = App::video(loader->objId());
|
||||||
if (video->loader) {
|
if (video->loader) {
|
||||||
|
video->status = FileReady;
|
||||||
if (video->loader->done()) {
|
if (video->loader->done()) {
|
||||||
video->finish();
|
video->finish();
|
||||||
QString already = video->already();
|
QString already = video->already();
|
||||||
|
@ -1614,7 +1637,17 @@ void MainWidget::loadFailed(mtpFileLoader *loader, bool started, const char *ret
|
||||||
if (started) {
|
if (started) {
|
||||||
connect(box, SIGNAL(confirmed()), this, retrySlot);
|
connect(box, SIGNAL(confirmed()), this, retrySlot);
|
||||||
} else {
|
} else {
|
||||||
connect(box, SIGNAL(confirmed()), App::wnd(), SLOT(showSettings()));
|
connect(box, SIGNAL(confirmed()), this, SLOT(onDownloadPathSettings()));
|
||||||
|
}
|
||||||
|
App::wnd()->showLayer(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::onDownloadPathSettings() {
|
||||||
|
cSetDownloadPath(QString());
|
||||||
|
cSetDownloadPathBookmark(QByteArray());
|
||||||
|
DownloadPathBox *box = new DownloadPathBox();
|
||||||
|
if (App::wnd() && App::wnd()->settingsWidget()) {
|
||||||
|
connect(box, SIGNAL(closed()), App::wnd()->settingsWidget(), SLOT(onDownloadPathEdited()));
|
||||||
}
|
}
|
||||||
App::wnd()->showLayer(box);
|
App::wnd()->showLayer(box);
|
||||||
}
|
}
|
||||||
|
@ -1634,6 +1667,7 @@ void MainWidget::videoLoadRetry() {
|
||||||
void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
|
void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
|
||||||
AudioData *audio = App::audio(loader->objId());
|
AudioData *audio = App::audio(loader->objId());
|
||||||
if (audio->loader) {
|
if (audio->loader) {
|
||||||
|
audio->status = FileReady;
|
||||||
if (audio->loader->done()) {
|
if (audio->loader->done()) {
|
||||||
audio->finish();
|
audio->finish();
|
||||||
QString already = audio->already();
|
QString already = audio->already();
|
||||||
|
@ -1688,7 +1722,7 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
|
||||||
if (f.write(audio->data) == audio->data.size()) {
|
if (f.write(audio->data) == audio->data.size()) {
|
||||||
f.close();
|
f.close();
|
||||||
already = filename;
|
already = filename;
|
||||||
audio->location = FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename);
|
audio->setLocation(FileLocation(StorageFilePartial, filename));
|
||||||
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputAudioFileLocation), audio->dc, audio->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputAudioFileLocation), audio->dc, audio->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1736,7 +1770,7 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) {
|
||||||
if (f.write(document->data) == document->data.size()) {
|
if (f.write(document->data) == document->data.size()) {
|
||||||
f.close();
|
f.close();
|
||||||
already = filename;
|
already = filename;
|
||||||
document->location = FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename);
|
document->setLocation(FileLocation(StorageFilePartial, filename));
|
||||||
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputDocumentFileLocation), document->dc, document->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputDocumentFileLocation), document->dc, document->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1793,6 +1827,7 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
||||||
bool songPlayActivated = false;
|
bool songPlayActivated = false;
|
||||||
DocumentData *document = App::document(loader->objId());
|
DocumentData *document = App::document(loader->objId());
|
||||||
if (document->loader) {
|
if (document->loader) {
|
||||||
|
document->status = FileReady;
|
||||||
if (document->loader->done()) {
|
if (document->loader->done()) {
|
||||||
document->finish();
|
document->finish();
|
||||||
QString already = document->already();
|
QString already = document->already();
|
||||||
|
@ -1813,11 +1848,13 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
songPlayActivated = true;
|
songPlayActivated = true;
|
||||||
} else if(document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
|
} else if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
|
||||||
QImageReader reader(already);
|
const FileLocation &location(document->location(true));
|
||||||
|
if (location.accessEnable()) {
|
||||||
|
QImageReader reader(location.name());
|
||||||
if (reader.canRead()) {
|
if (reader.canRead()) {
|
||||||
if (reader.supportsAnimation() && reader.imageCount() > 1 && item) {
|
if (reader.supportsAnimation() && reader.imageCount() > 1 && item) {
|
||||||
startGif(item, already);
|
startGif(item, location);
|
||||||
} else if (item) {
|
} else if (item) {
|
||||||
App::wnd()->showDocument(document, item);
|
App::wnd()->showDocument(document, item);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1826,6 +1863,10 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
||||||
} else {
|
} else {
|
||||||
psOpenFile(already);
|
psOpenFile(already);
|
||||||
}
|
}
|
||||||
|
location.accessDisable();
|
||||||
|
} else {
|
||||||
|
psOpenFile(already);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
QPoint pos(QCursor::pos());
|
QPoint pos(QCursor::pos());
|
||||||
if (document->openOnSave < 0 && !psShowOpenWithMenu(pos.x(), pos.y(), already)) {
|
if (document->openOnSave < 0 && !psShowOpenWithMenu(pos.x(), pos.y(), already)) {
|
||||||
|
@ -2320,7 +2361,9 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (!dialogs.isHidden()) {
|
if (!dialogs.isHidden()) {
|
||||||
|
if (!back) {
|
||||||
dialogs.scrollToPeer(peerId, showAtMsgId);
|
dialogs.scrollToPeer(peerId, showAtMsgId);
|
||||||
|
}
|
||||||
dialogs.update();
|
dialogs.update();
|
||||||
}
|
}
|
||||||
App::wnd()->getTitle()->updateBackButton();
|
App::wnd()->getTitle()->updateBackButton();
|
||||||
|
@ -2491,6 +2534,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop)
|
||||||
if (back) clearBotStartToken(history.peer());
|
if (back) clearBotStartToken(history.peer());
|
||||||
history.showHistory(0, 0);
|
history.showHistory(0, 0);
|
||||||
history.hide();
|
history.hide();
|
||||||
|
if (!cWideMode()) dialogs.hide();
|
||||||
|
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
|
|
||||||
|
@ -2537,6 +2581,7 @@ void MainWidget::orderWidgets() {
|
||||||
dialogs.raise();
|
dialogs.raise();
|
||||||
_mediaType.raise();
|
_mediaType.raise();
|
||||||
if (_hider) _hider->raise();
|
if (_hider) _hider->raise();
|
||||||
|
if (_stickerPreview) _stickerPreview->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect MainWidget::historyRect() const {
|
QRect MainWidget::historyRect() const {
|
||||||
|
@ -2690,6 +2735,7 @@ void MainWidget::hideAll() {
|
||||||
_topBar.hide();
|
_topBar.hide();
|
||||||
_mediaType.hide();
|
_mediaType.hide();
|
||||||
_player.hide();
|
_player.hide();
|
||||||
|
_playerHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::showAll() {
|
void MainWidget::showAll() {
|
||||||
|
@ -2764,6 +2810,7 @@ void MainWidget::showAll() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
resizeEvent(0);
|
||||||
|
|
||||||
App::wnd()->checkHistoryActivation();
|
App::wnd()->checkHistoryActivation();
|
||||||
}
|
}
|
||||||
|
@ -2795,6 +2842,7 @@ void MainWidget::resizeEvent(QResizeEvent *e) {
|
||||||
_mediaType.moveToLeft(width() - _mediaType.width(), _playerHeight + st::topBarHeight);
|
_mediaType.moveToLeft(width() - _mediaType.width(), _playerHeight + st::topBarHeight);
|
||||||
if (profile) profile->setGeometry(history.geometry());
|
if (profile) profile->setGeometry(history.geometry());
|
||||||
if (overview) overview->setGeometry(history.geometry());
|
if (overview) overview->setGeometry(history.geometry());
|
||||||
|
if (_stickerPreview) _stickerPreview->setGeometry(rect());
|
||||||
_contentScrollAddToY = 0;
|
_contentScrollAddToY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3668,6 +3716,7 @@ void MainWidget::startFull(const MTPVector<MTPUser> &users) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNotifySettings &settings, History *h) {
|
void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNotifySettings &settings, History *h) {
|
||||||
|
PeerData *updatePeer = 0;
|
||||||
switch (settings.type()) {
|
switch (settings.type()) {
|
||||||
case mtpc_peerNotifySettingsEmpty:
|
case mtpc_peerNotifySettingsEmpty:
|
||||||
switch (peer.type()) {
|
switch (peer.type()) {
|
||||||
|
@ -3675,18 +3724,15 @@ void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNoti
|
||||||
case mtpc_notifyUsers: globalNotifyUsersPtr = EmptyNotifySettings; break;
|
case mtpc_notifyUsers: globalNotifyUsersPtr = EmptyNotifySettings; break;
|
||||||
case mtpc_notifyChats: globalNotifyChatsPtr = EmptyNotifySettings; break;
|
case mtpc_notifyChats: globalNotifyChatsPtr = EmptyNotifySettings; break;
|
||||||
case mtpc_notifyPeer: {
|
case mtpc_notifyPeer: {
|
||||||
PeerData *data = App::peerLoaded(peerFromMTP(peer.c_notifyPeer().vpeer));
|
updatePeer = App::peerLoaded(peerFromMTP(peer.c_notifyPeer().vpeer));
|
||||||
if (data && data->notify != EmptyNotifySettings) {
|
if (updatePeer && updatePeer->notify != EmptyNotifySettings) {
|
||||||
if (data->notify != UnknownNotifySettings) {
|
if (updatePeer->notify != UnknownNotifySettings) {
|
||||||
delete data->notify;
|
delete updatePeer->notify;
|
||||||
}
|
}
|
||||||
data->notify = EmptyNotifySettings;
|
updatePeer->notify = EmptyNotifySettings;
|
||||||
App::unregMuted(data);
|
App::unregMuted(updatePeer);
|
||||||
if (!h) h = App::history(data->id);
|
if (!h) h = App::history(updatePeer->id);
|
||||||
h->setMute(false);
|
h->setMute(false);
|
||||||
if (history.peer() == data) {
|
|
||||||
history.updateNotifySettings();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@ -3694,19 +3740,18 @@ void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNoti
|
||||||
case mtpc_peerNotifySettings: {
|
case mtpc_peerNotifySettings: {
|
||||||
const MTPDpeerNotifySettings &d(settings.c_peerNotifySettings());
|
const MTPDpeerNotifySettings &d(settings.c_peerNotifySettings());
|
||||||
NotifySettingsPtr setTo = UnknownNotifySettings;
|
NotifySettingsPtr setTo = UnknownNotifySettings;
|
||||||
PeerData *data = 0;
|
|
||||||
switch (peer.type()) {
|
switch (peer.type()) {
|
||||||
case mtpc_notifyAll: setTo = globalNotifyAllPtr = &globalNotifyAll; break;
|
case mtpc_notifyAll: setTo = globalNotifyAllPtr = &globalNotifyAll; break;
|
||||||
case mtpc_notifyUsers: setTo = globalNotifyUsersPtr = &globalNotifyUsers; break;
|
case mtpc_notifyUsers: setTo = globalNotifyUsersPtr = &globalNotifyUsers; break;
|
||||||
case mtpc_notifyChats: setTo = globalNotifyChatsPtr = &globalNotifyChats; break;
|
case mtpc_notifyChats: setTo = globalNotifyChatsPtr = &globalNotifyChats; break;
|
||||||
case mtpc_notifyPeer: {
|
case mtpc_notifyPeer: {
|
||||||
data = App::peerLoaded(peerFromMTP(peer.c_notifyPeer().vpeer));
|
updatePeer = App::peerLoaded(peerFromMTP(peer.c_notifyPeer().vpeer));
|
||||||
if (!data) break;
|
if (!updatePeer) break;
|
||||||
|
|
||||||
if (data->notify == UnknownNotifySettings || data->notify == EmptyNotifySettings) {
|
if (updatePeer->notify == UnknownNotifySettings || updatePeer->notify == EmptyNotifySettings) {
|
||||||
data->notify = new NotifySettings();
|
updatePeer->notify = new NotifySettings();
|
||||||
}
|
}
|
||||||
setTo = data->notify;
|
setTo = updatePeer->notify;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
if (setTo == UnknownNotifySettings) break;
|
if (setTo == UnknownNotifySettings) break;
|
||||||
|
@ -3715,26 +3760,29 @@ void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNoti
|
||||||
setTo->sound = d.vsound.c_string().v;
|
setTo->sound = d.vsound.c_string().v;
|
||||||
setTo->previews = mtpIsTrue(d.vshow_previews);
|
setTo->previews = mtpIsTrue(d.vshow_previews);
|
||||||
setTo->events = d.vevents_mask.v;
|
setTo->events = d.vevents_mask.v;
|
||||||
if (data) {
|
if (updatePeer) {
|
||||||
if (!h) h = App::history(data->id);
|
if (!h) h = App::history(updatePeer->id);
|
||||||
int32 changeIn = 0;
|
int32 changeIn = 0;
|
||||||
if (isNotifyMuted(setTo, &changeIn)) {
|
if (isNotifyMuted(setTo, &changeIn)) {
|
||||||
App::wnd()->notifyClear(h);
|
App::wnd()->notifyClear(h);
|
||||||
h->setMute(true);
|
h->setMute(true);
|
||||||
App::regMuted(data, changeIn);
|
App::regMuted(updatePeer, changeIn);
|
||||||
} else {
|
} else {
|
||||||
h->setMute(false);
|
h->setMute(false);
|
||||||
}
|
}
|
||||||
if (history.peer() == data) {
|
|
||||||
history.updateNotifySettings();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile) {
|
if (updatePeer) {
|
||||||
|
if (history.peer() == updatePeer) {
|
||||||
|
history.updateNotifySettings();
|
||||||
|
}
|
||||||
|
dialogs.updateNotifySettings(updatePeer);
|
||||||
|
if (profile && profile->peer() == updatePeer) {
|
||||||
profile->updateNotifySettings();
|
profile->updateNotifySettings();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::gotNotifySetting(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings) {
|
void MainWidget::gotNotifySetting(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings) {
|
||||||
|
@ -4573,5 +4621,81 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case mtpc_updateNewStickerSet: {
|
||||||
|
const MTPDupdateNewStickerSet &d(update.c_updateNewStickerSet());
|
||||||
|
if (d.vstickerset.type() == mtpc_messages_stickerSet) {
|
||||||
|
const MTPDmessages_stickerSet &set(d.vstickerset.c_messages_stickerSet());
|
||||||
|
if (set.vset.type() == mtpc_stickerSet) {
|
||||||
|
const QVector<MTPDocument> &v(set.vdocuments.c_vector().v);
|
||||||
|
StickerPack pack;
|
||||||
|
pack.reserve(v.size());
|
||||||
|
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||||
|
DocumentData *doc = App::feedDocument(v.at(i));
|
||||||
|
if (!doc || !doc->sticker()) continue;
|
||||||
|
|
||||||
|
pack.push_back(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MTPDstickerSet &s(set.vset.c_stickerSet());
|
||||||
|
|
||||||
|
StickerSets &sets(cRefStickerSets());
|
||||||
|
|
||||||
|
sets.insert(s.vid.v, StickerSet(s.vid.v, s.vaccess_hash.v, stickerSetTitle(s), qs(s.vshort_name), s.vcount.v, s.vhash.v, s.vflags.v)).value().stickers = pack;
|
||||||
|
|
||||||
|
StickerSetsOrder &order(cRefStickerSetsOrder());
|
||||||
|
int32 insertAtIndex = 0, currentIndex = order.indexOf(s.vid.v);
|
||||||
|
if (currentIndex != insertAtIndex) {
|
||||||
|
if (currentIndex > 0) {
|
||||||
|
order.removeAt(currentIndex);
|
||||||
|
}
|
||||||
|
order.insert(insertAtIndex, s.vid.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
||||||
|
if (custom != sets.cend()) {
|
||||||
|
for (int32 i = 0, l = pack.size(); i < l; ++i) {
|
||||||
|
int32 removeIndex = custom->stickers.indexOf(pack.at(i));
|
||||||
|
if (removeIndex >= 0) custom->stickers.removeAt(removeIndex);
|
||||||
|
}
|
||||||
|
if (custom->stickers.isEmpty()) {
|
||||||
|
sets.erase(custom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cSetStickersHash(stickersCountHash());
|
||||||
|
Local::writeStickers();
|
||||||
|
emit stickersUpdated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mtpc_updateStickerSetsOrder: {
|
||||||
|
const MTPDupdateStickerSetsOrder &d(update.c_updateStickerSetsOrder());
|
||||||
|
const QVector<MTPlong> &order(d.vorder.c_vector().v);
|
||||||
|
const StickerSets &sets(cStickerSets());
|
||||||
|
StickerSetsOrder result;
|
||||||
|
for (int32 i = 0, l = order.size(); i < l; ++i) {
|
||||||
|
if (sets.constFind(order.at(i).v) == sets.cend()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.push_back(order.at(i).v);
|
||||||
|
}
|
||||||
|
if (result.size() != cStickerSetsOrder().size() || result.size() != order.size()) {
|
||||||
|
cSetLastStickersUpdate(0);
|
||||||
|
cSetStickersHash(0);
|
||||||
|
App::main()->updateStickers();
|
||||||
|
} else {
|
||||||
|
cSetStickerSetsOrder(result);
|
||||||
|
cSetStickersHash(stickersCountHash());
|
||||||
|
Local::writeStickers();
|
||||||
|
emit stickersUpdated();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mtpc_updateStickerSets: {
|
||||||
|
cSetLastStickersUpdate(0);
|
||||||
|
cSetStickersHash(0);
|
||||||
|
App::main()->updateStickers();
|
||||||
|
} break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StickerPreviewWidget;
|
||||||
|
|
||||||
class MainWidget : public TWidget, public RPCSender {
|
class MainWidget : public TWidget, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -412,6 +414,9 @@ public:
|
||||||
QPixmap grabTopBar();
|
QPixmap grabTopBar();
|
||||||
QPixmap grabInner();
|
QPixmap grabInner();
|
||||||
|
|
||||||
|
void ui_showStickerPreview(DocumentData *sticker);
|
||||||
|
void ui_hideStickerPreview();
|
||||||
|
|
||||||
~MainWidget();
|
~MainWidget();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -482,6 +487,8 @@ public slots:
|
||||||
void onViewsIncrement();
|
void onViewsIncrement();
|
||||||
void onActiveChannelUpdateFull();
|
void onActiveChannelUpdateFull();
|
||||||
|
|
||||||
|
void onDownloadPathSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void sendReadRequest(PeerData *peer, MsgId upTo);
|
void sendReadRequest(PeerData *peer, MsgId upTo);
|
||||||
|
@ -563,6 +570,8 @@ private:
|
||||||
PeerData *_peerInStack;
|
PeerData *_peerInStack;
|
||||||
MsgId _msgIdInStack;
|
MsgId _msgIdInStack;
|
||||||
|
|
||||||
|
StickerPreviewWidget *_stickerPreview;
|
||||||
|
|
||||||
int32 _playerHeight;
|
int32 _playerHeight;
|
||||||
int32 _contentScrollAddToY;
|
int32 _contentScrollAddToY;
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ MediaView::MediaView() : TWidget(App::wnd())
|
||||||
connect(_btnSaveCancel, SIGNAL(clicked()), this, SLOT(onSaveCancel()));
|
connect(_btnSaveCancel, SIGNAL(clicked()), this, SLOT(onSaveCancel()));
|
||||||
_btns.push_back(_btnToMessage = _dropdown.addButton(new IconedButton(this, st::mvButton, lang(lng_context_to_msg))));
|
_btns.push_back(_btnToMessage = _dropdown.addButton(new IconedButton(this, st::mvButton, lang(lng_context_to_msg))));
|
||||||
connect(_btnToMessage, SIGNAL(clicked()), this, SLOT(onToMessage()));
|
connect(_btnToMessage, SIGNAL(clicked()), this, SLOT(onToMessage()));
|
||||||
_btns.push_back(_btnShowInFolder = _dropdown.addButton(new IconedButton(this, st::mvButton, lang(cPlatform() == dbipMac ? lng_context_show_in_finder : lng_context_show_in_folder))));
|
_btns.push_back(_btnShowInFolder = _dropdown.addButton(new IconedButton(this, st::mvButton, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder))));
|
||||||
connect(_btnShowInFolder, SIGNAL(clicked()), this, SLOT(onShowInFolder()));
|
connect(_btnShowInFolder, SIGNAL(clicked()), this, SLOT(onShowInFolder()));
|
||||||
_btns.push_back(_btnCopy = _dropdown.addButton(new IconedButton(this, st::mvButton, lang(lng_mediaview_copy))));
|
_btns.push_back(_btnCopy = _dropdown.addButton(new IconedButton(this, st::mvButton, lang(lng_mediaview_copy))));
|
||||||
connect(_btnCopy, SIGNAL(clicked()), this, SLOT(onCopy()));
|
connect(_btnCopy, SIGNAL(clicked()), this, SLOT(onCopy()));
|
||||||
|
@ -453,11 +453,14 @@ bool MediaView::animStep(float64 msp) {
|
||||||
_docRadialFirst = _docRadialLast = _docRadialStart = 0;
|
_docRadialFirst = _docRadialLast = _docRadialStart = 0;
|
||||||
a_docRadial = anim::fvalue(0, 0);
|
a_docRadial = anim::fvalue(0, 0);
|
||||||
if (!_doc->already().isEmpty() && _doc->size < MediaViewImageSizeLimit) {
|
if (!_doc->already().isEmpty() && _doc->size < MediaViewImageSizeLimit) {
|
||||||
QString fname(_doc->already(true));
|
const FileLocation &location(_doc->location(true));
|
||||||
QImageReader reader(fname);
|
if (location.accessEnable()) {
|
||||||
|
QImageReader reader(location.name());
|
||||||
if (reader.canRead()) {
|
if (reader.canRead()) {
|
||||||
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
|
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
|
||||||
}
|
}
|
||||||
|
location.accessDisable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
float64 r = dt / st::radialDuration;
|
float64 r = dt / st::radialDuration;
|
||||||
|
@ -529,20 +532,9 @@ void MediaView::onToMessage() {
|
||||||
void MediaView::onSaveAs() {
|
void MediaView::onSaveAs() {
|
||||||
QString file;
|
QString file;
|
||||||
if (_doc) {
|
if (_doc) {
|
||||||
QString cur = _doc->already(true);
|
const FileLocation &location(_doc->location(true));
|
||||||
if (cur.isEmpty()) {
|
if (location.accessEnable()) {
|
||||||
if (_current.isNull() && _currentGif.isNull()) {
|
QFileInfo alreadyInfo(location.name());
|
||||||
DocumentSaveLink::doSave(_doc, true);
|
|
||||||
updateControls();
|
|
||||||
} else {
|
|
||||||
_saveVisible = false;
|
|
||||||
update(_saveNav);
|
|
||||||
}
|
|
||||||
updateOver(_lastMouseMovePos);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfo alreadyInfo(cur);
|
|
||||||
QDir alreadyDir(alreadyInfo.dir());
|
QDir alreadyDir(alreadyInfo.dir());
|
||||||
QString name = alreadyInfo.fileName(), filter;
|
QString name = alreadyInfo.fileName(), filter;
|
||||||
MimeType mimeType = mimeTypeForName(_doc->mime);
|
MimeType mimeType = mimeTypeForName(_doc->mime);
|
||||||
|
@ -561,8 +553,20 @@ void MediaView::onSaveAs() {
|
||||||
psBringToBack(this);
|
psBringToBack(this);
|
||||||
file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir);
|
file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir);
|
||||||
psShowOverAll(this);
|
psShowOverAll(this);
|
||||||
if (!file.isEmpty() && file != cur) {
|
if (!file.isEmpty() && file != location.name()) {
|
||||||
QFile(cur).copy(file);
|
QFile(location.name()).copy(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
location.accessDisable();
|
||||||
|
} else {
|
||||||
|
if (_current.isNull() && _currentGif.isNull()) {
|
||||||
|
DocumentSaveLink::doSave(_doc, true);
|
||||||
|
updateControls();
|
||||||
|
} else {
|
||||||
|
_saveVisible = false;
|
||||||
|
update(_saveNav);
|
||||||
|
}
|
||||||
|
updateOver(_lastMouseMovePos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_photo || !_photo->full->loaded()) return;
|
if (!_photo || !_photo->full->loaded()) return;
|
||||||
|
@ -609,8 +613,15 @@ void MediaView::onDownload() {
|
||||||
}
|
}
|
||||||
QString toName;
|
QString toName;
|
||||||
if (_doc) {
|
if (_doc) {
|
||||||
QString cur = _doc->already(true);
|
const FileLocation &location(_doc->location(true));
|
||||||
if (cur.isEmpty()) {
|
if (location.accessEnable()) {
|
||||||
|
if (!QDir().exists(path)) QDir().mkpath(path);
|
||||||
|
toName = filedialogNextFilename(_doc->name, location.name(), path);
|
||||||
|
if (toName != location.name() && !QFile(location.name()).copy(toName)) {
|
||||||
|
toName = QString();
|
||||||
|
}
|
||||||
|
location.accessDisable();
|
||||||
|
} else {
|
||||||
if (_current.isNull() && _currentGif.isNull()) {
|
if (_current.isNull() && _currentGif.isNull()) {
|
||||||
DocumentSaveLink::doSave(_doc);
|
DocumentSaveLink::doSave(_doc);
|
||||||
updateControls();
|
updateControls();
|
||||||
|
@ -619,12 +630,6 @@ void MediaView::onDownload() {
|
||||||
update(_saveNav);
|
update(_saveNav);
|
||||||
}
|
}
|
||||||
updateOver(_lastMouseMovePos);
|
updateOver(_lastMouseMovePos);
|
||||||
} else {
|
|
||||||
if (!QDir().exists(path)) QDir().mkpath(path);
|
|
||||||
toName = filedialogNextFilename(_doc->name, cur, path);
|
|
||||||
if (toName != cur && !QFile(cur).copy(toName)) {
|
|
||||||
toName = QString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_photo || !_photo->full->loaded()) {
|
if (!_photo || !_photo->full->loaded()) {
|
||||||
|
@ -902,25 +907,26 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
|
||||||
|
|
||||||
_caption = Text();
|
_caption = Text();
|
||||||
if (_doc) {
|
if (_doc) {
|
||||||
QString already = _doc->already(true);
|
const FileLocation &location(_doc->location(true));
|
||||||
if (_doc->sticker() && !_doc->sticker()->img->isNull() && _doc->sticker()->img->loaded()) {
|
if (_doc->sticker() && !_doc->sticker()->img->isNull() && _doc->sticker()->img->loaded()) {
|
||||||
_currentGif.stop();
|
_currentGif.stop();
|
||||||
_current = _doc->sticker()->img->pix();
|
_current = _doc->sticker()->img->pix();
|
||||||
} else if (!already.isEmpty()) {
|
} else if (location.accessEnable()) {
|
||||||
QImageReader reader(already);
|
QImageReader reader(location.name());
|
||||||
if (reader.canRead()) {
|
if (reader.canRead()) {
|
||||||
if (reader.supportsAnimation() && reader.imageCount() > 1) {
|
if (reader.supportsAnimation() && reader.imageCount() > 1) {
|
||||||
_currentGif.start(0, already);
|
_currentGif.start(0, location);
|
||||||
_current = QPixmap();
|
_current = QPixmap();
|
||||||
} else {
|
} else {
|
||||||
_currentGif.stop();
|
_currentGif.stop();
|
||||||
QPixmap pix = QPixmap::fromImage(App::readImage(already, 0, false), Qt::ColorOnly);
|
QPixmap pix = QPixmap::fromImage(App::readImage(location.name(), 0, false), Qt::ColorOnly);
|
||||||
_current = pix;
|
_current = pix;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_currentGif.stop();
|
_currentGif.stop();
|
||||||
_current = QPixmap();
|
_current = QPixmap();
|
||||||
}
|
}
|
||||||
|
location.accessDisable();
|
||||||
} else {
|
} else {
|
||||||
_currentGif.stop();
|
_currentGif.stop();
|
||||||
_current = QPixmap();
|
_current = QPixmap();
|
||||||
|
|
41
Telegram/SourceFiles/mtproto/mtpAuthKey.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop 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.
|
||||||
|
|
||||||
|
It 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.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
void aesEncrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
||||||
|
uchar aes_key[32], aes_iv[32];
|
||||||
|
memcpy(aes_key, key, 32);
|
||||||
|
memcpy(aes_iv, iv, 32);
|
||||||
|
|
||||||
|
AES_KEY aes;
|
||||||
|
AES_set_encrypt_key(aes_key, 256, &aes);
|
||||||
|
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_ENCRYPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void aesDecrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
||||||
|
uchar aes_key[32], aes_iv[32];
|
||||||
|
memcpy(aes_key, key, 32);
|
||||||
|
memcpy(aes_iv, iv, 32);
|
||||||
|
|
||||||
|
AES_KEY aes;
|
||||||
|
AES_set_decrypt_key(aes_key, 256, &aes);
|
||||||
|
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_DECRYPT);
|
||||||
|
}
|
|
@ -112,15 +112,8 @@ inline bool operator==(const mtpAuthKey &a, const mtpAuthKey &b) {
|
||||||
typedef QSharedPointer<mtpAuthKey> mtpAuthKeyPtr;
|
typedef QSharedPointer<mtpAuthKey> mtpAuthKeyPtr;
|
||||||
typedef QVector<mtpAuthKeyPtr> mtpKeysMap;
|
typedef QVector<mtpAuthKeyPtr> mtpKeysMap;
|
||||||
|
|
||||||
inline void aesEncrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
void aesEncrypt(const void *src, void *dst, uint32 len, void *key, void *iv);
|
||||||
uchar aes_key[32], aes_iv[32];
|
void aesDecrypt(const void *src, void *dst, uint32 len, void *key, void *iv);
|
||||||
memcpy(aes_key, key, 32);
|
|
||||||
memcpy(aes_iv, iv, 32);
|
|
||||||
|
|
||||||
AES_KEY aes;
|
|
||||||
AES_set_encrypt_key(aes_key, 256, &aes);
|
|
||||||
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_ENCRYPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void aesEncrypt(const void *src, void *dst, uint32 len, const mtpAuthKeyPtr &authKey, const MTPint128 &msgKey) {
|
inline void aesEncrypt(const void *src, void *dst, uint32 len, const mtpAuthKeyPtr &authKey, const MTPint128 &msgKey) {
|
||||||
MTPint256 aesKey, aesIV;
|
MTPint256 aesKey, aesIV;
|
||||||
|
@ -136,16 +129,6 @@ inline void aesEncryptLocal(const void *src, void *dst, uint32 len, const mtpAut
|
||||||
return aesEncrypt(src, dst, len, &aesKey, &aesIV);
|
return aesEncrypt(src, dst, len, &aesKey, &aesIV);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void aesDecrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
|
||||||
uchar aes_key[32], aes_iv[32];
|
|
||||||
memcpy(aes_key, key, 32);
|
|
||||||
memcpy(aes_iv, iv, 32);
|
|
||||||
|
|
||||||
AES_KEY aes;
|
|
||||||
AES_set_decrypt_key(aes_key, 256, &aes);
|
|
||||||
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_DECRYPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void aesDecrypt(const void *src, void *dst, uint32 len, const mtpAuthKeyPtr &authKey, const MTPint128 &msgKey) {
|
inline void aesDecrypt(const void *src, void *dst, uint32 len, const mtpAuthKeyPtr &authKey, const MTPint128 &msgKey) {
|
||||||
MTPint256 aesKey, aesIV;
|
MTPint256 aesKey, aesIV;
|
||||||
authKey->prepareAES(msgKey, aesKey, aesIV, false);
|
authKey->prepareAES(msgKey, aesKey, aesIV, false);
|
||||||
|
|
|
@ -361,7 +361,7 @@ namespace {
|
||||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||||
if (statusCode.isValid()) {
|
if (statusCode.isValid()) {
|
||||||
int status = statusCode.toInt();
|
int status = statusCode.toInt();
|
||||||
mayBeBadKey = (status == 404);
|
mayBeBadKey = (status == 410);
|
||||||
if (status == 429) {
|
if (status == 429) {
|
||||||
LOG(("Protocol Error: 429 flood code returned!"));
|
LOG(("Protocol Error: 429 flood code returned!"));
|
||||||
}
|
}
|
||||||
|
@ -845,7 +845,7 @@ void MTPautoConnection::socketPacket(mtpPrime *packet, uint32 size) {
|
||||||
sock.disconnectFromHost();
|
sock.disconnectFromHost();
|
||||||
emit connected();
|
emit connected();
|
||||||
} else if (status == WaitingTcp || status == UsingTcp) {
|
} else if (status == WaitingTcp || status == UsingTcp) {
|
||||||
bool mayBeBadKey = (data[0] == -404) && _sentEncrypted;
|
bool mayBeBadKey = (data[0] == -410) && _sentEncrypted;
|
||||||
emit error(mayBeBadKey);
|
emit error(mayBeBadKey);
|
||||||
} else {
|
} else {
|
||||||
LOG(("Strange Tcp Error; status %1").arg(status));
|
LOG(("Strange Tcp Error; status %1").arg(status));
|
||||||
|
@ -1016,7 +1016,7 @@ void MTPtcpConnection::socketPacket(mtpPrime *packet, uint32 size) {
|
||||||
|
|
||||||
mtpBuffer data = _handleTcpResponse(packet, size);
|
mtpBuffer data = _handleTcpResponse(packet, size);
|
||||||
if (data.size() == 1) {
|
if (data.size() == 1) {
|
||||||
bool mayBeBadKey = (data[0] == -404) && _sentEncrypted;
|
bool mayBeBadKey = (data[0] == -410) && _sentEncrypted;
|
||||||
emit error(mayBeBadKey);
|
emit error(mayBeBadKey);
|
||||||
} else if (status == UsingTcp) {
|
} else if (status == UsingTcp) {
|
||||||
receivedQueue.push_back(data);
|
receivedQueue.push_back(data);
|
||||||
|
@ -1952,11 +1952,11 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTProtoConnectionPrivate::restart(bool maybeBadKey) {
|
void MTProtoConnectionPrivate::restart(bool mayBeBadKey) {
|
||||||
QReadLocker lockFinished(&sessionDataMutex);
|
QReadLocker lockFinished(&sessionDataMutex);
|
||||||
if (!sessionData) return;
|
if (!sessionData) return;
|
||||||
|
|
||||||
DEBUG_LOG(("MTP Info: restarting MTProtoConnection, maybe bad key = %1").arg(logBool(maybeBadKey)));
|
DEBUG_LOG(("MTP Info: restarting MTProtoConnection, maybe bad key = %1").arg(logBool(mayBeBadKey)));
|
||||||
|
|
||||||
_waitForReceivedTimer.stop();
|
_waitForReceivedTimer.stop();
|
||||||
_waitForConnectedTimer.stop();
|
_waitForConnectedTimer.stop();
|
||||||
|
@ -1964,11 +1964,11 @@ void MTProtoConnectionPrivate::restart(bool maybeBadKey) {
|
||||||
mtpAuthKeyPtr key(sessionData->getKey());
|
mtpAuthKeyPtr key(sessionData->getKey());
|
||||||
if (key) {
|
if (key) {
|
||||||
if (!sessionData->isCheckedKey()) {
|
if (!sessionData->isCheckedKey()) {
|
||||||
if (maybeBadKey) {
|
if (mayBeBadKey) {
|
||||||
clearMessages();
|
clearMessages();
|
||||||
keyId = mtpAuthKey::RecreateKeyId;
|
keyId = mtpAuthKey::RecreateKeyId;
|
||||||
// retryTimeout = 1; // no ddos please
|
// retryTimeout = 1; // no ddos please
|
||||||
LOG(("MTP Info: key may be bad and was not checked - will be destroyed"));
|
LOG(("MTP Info: key may be bad and was not checked - but won't be destroyed, no log outs because of bad server right now.."));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sessionData->setCheckedKey(false);
|
sessionData->setCheckedKey(false);
|
||||||
|
|
|
@ -135,7 +135,7 @@ signals:
|
||||||
void receivedData();
|
void receivedData();
|
||||||
void receivedSome(); // to stop restart timer
|
void receivedSome(); // to stop restart timer
|
||||||
|
|
||||||
void error(bool maybeBadKey = false);
|
void error(bool mayBeBadKey = false);
|
||||||
|
|
||||||
void connected();
|
void connected();
|
||||||
void disconnected();
|
void disconnected();
|
||||||
|
@ -355,7 +355,7 @@ public slots:
|
||||||
|
|
||||||
void retryByTimer();
|
void retryByTimer();
|
||||||
void restartNow();
|
void restartNow();
|
||||||
void restart(bool maybeBadKey = false);
|
void restart(bool mayBeBadKey = false);
|
||||||
|
|
||||||
void onPingSender();
|
void onPingSender();
|
||||||
void onPingSendForce();
|
void onPingSendForce();
|
||||||
|
@ -375,8 +375,8 @@ public slots:
|
||||||
void onConnected6();
|
void onConnected6();
|
||||||
void onDisconnected4();
|
void onDisconnected4();
|
||||||
void onDisconnected6();
|
void onDisconnected6();
|
||||||
void onError4(bool maybeBadKey = false);
|
void onError4(bool mayBeBadKey = false);
|
||||||
void onError6(bool maybeBadKey = false);
|
void onError6(bool mayBeBadKey = false);
|
||||||
|
|
||||||
void doFinish();
|
void doFinish();
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "mtpCoreTypes.h"
|
#include "mtpCoreTypes.h"
|
||||||
|
|
||||||
|
#include "lang.h"
|
||||||
|
|
||||||
#if defined _DEBUG || defined _WITH_DEBUG
|
#if defined _DEBUG || defined _WITH_DEBUG
|
||||||
|
|
||||||
QString mtpWrapNumber(float64 number) {
|
QString mtpWrapNumber(float64 number) {
|
||||||
|
@ -150,3 +152,11 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString stickerSetTitle(const MTPDstickerSet &s) {
|
||||||
|
QString title = qs(s.vtitle);
|
||||||
|
if ((s.vflags.v & MTPDstickerSet::flag_official) && !title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) {
|
||||||
|
return lang(lng_stickers_default_set);
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
|
@ -368,7 +368,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||||
mtpTypeId(mtpc_invokeWithLayer18),
|
mtpTypeId(mtpc_invokeWithLayer18),
|
||||||
};
|
};
|
||||||
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||||
static const mtpPrime mtpCurrentLayer = 42;
|
static const mtpPrime mtpCurrentLayer = 43;
|
||||||
|
|
||||||
template <typename bareT>
|
template <typename bareT>
|
||||||
class MTPBoxed : public bareT {
|
class MTPBoxed : public bareT {
|
||||||
|
@ -990,3 +990,5 @@ enum { // client side flags
|
||||||
|
|
||||||
static const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_int(0), MTP_vector<MTPKeyboardButtonRow>(0));
|
static const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_int(0), MTP_vector<MTPKeyboardButtonRow>(0));
|
||||||
static const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0);
|
static const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0);
|
||||||
|
|
||||||
|
QString stickerSetTitle(const MTPDstickerSet &s);
|
|
@ -2082,6 +2082,31 @@ void _serialize_wallPaperSolid(MTPStringLogger &to, int32 stage, int32 lev, Type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_inputReportReasonSpam(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ inputReportReasonSpam }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _serialize_inputReportReasonViolence(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ inputReportReasonViolence }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _serialize_inputReportReasonPornography(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ inputReportReasonPornography }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _serialize_inputReportReasonOther(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ inputReportReasonOther");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" text: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_userFull(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_userFull(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -2966,6 +2991,36 @@ void _serialize_updateChatParticipantAdmin(MTPStringLogger &to, int32 stage, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_updateNewStickerSet(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ updateNewStickerSet");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" stickerset: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _serialize_updateStickerSetsOrder(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ updateStickerSetsOrder");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" order: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _serialize_updateStickerSets(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ updateStickerSets }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -4052,7 +4107,7 @@ void _serialize_messages_allStickers(MTPStringLogger &to, int32 stage, int32 lev
|
||||||
to.add("\n").addSpaces(lev);
|
to.add("\n").addSpaces(lev);
|
||||||
}
|
}
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" hash: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" sets: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 1: to.add(" sets: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
|
@ -4970,6 +5025,19 @@ void _serialize_channels_channelParticipant(MTPStringLogger &to, int32 stage, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_help_termsOfService(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ help_termsOfService");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" text: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_req_pq(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_req_pq(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -5229,6 +5297,20 @@ void _serialize_account_updateStatus(MTPStringLogger &to, int32 stage, int32 lev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_account_reportPeer(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ account_reportPeer");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 1: to.add(" reason: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_account_checkUsername(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_account_checkUsername(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -5457,6 +5539,19 @@ void _serialize_messages_editChatAdmin(MTPStringLogger &to, int32 stage, int32 l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_messages_reorderStickerSets(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ messages_reorderStickerSets");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" order: "); ++stages.back(); types.push_back(0); vtypes.push_back(mtpc_long); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_upload_saveFilePart(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_upload_saveFilePart(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -6835,7 +6930,7 @@ void _serialize_messages_getAllStickers(MTPStringLogger &to, int32 stage, int32
|
||||||
to.add("\n").addSpaces(lev);
|
to.add("\n").addSpaces(lev);
|
||||||
}
|
}
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" hash: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7058,6 +7153,19 @@ void _serialize_help_getAppChangelog(MTPStringLogger &to, int32 stage, int32 lev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_help_getTermsOfService(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ help_getTermsOfService");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_channels_getParticipants(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_channels_getParticipants(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -7305,6 +7413,10 @@ namespace {
|
||||||
_serializers.insert(mtpc_peerNotifySettings, _serialize_peerNotifySettings);
|
_serializers.insert(mtpc_peerNotifySettings, _serialize_peerNotifySettings);
|
||||||
_serializers.insert(mtpc_wallPaper, _serialize_wallPaper);
|
_serializers.insert(mtpc_wallPaper, _serialize_wallPaper);
|
||||||
_serializers.insert(mtpc_wallPaperSolid, _serialize_wallPaperSolid);
|
_serializers.insert(mtpc_wallPaperSolid, _serialize_wallPaperSolid);
|
||||||
|
_serializers.insert(mtpc_inputReportReasonSpam, _serialize_inputReportReasonSpam);
|
||||||
|
_serializers.insert(mtpc_inputReportReasonViolence, _serialize_inputReportReasonViolence);
|
||||||
|
_serializers.insert(mtpc_inputReportReasonPornography, _serialize_inputReportReasonPornography);
|
||||||
|
_serializers.insert(mtpc_inputReportReasonOther, _serialize_inputReportReasonOther);
|
||||||
_serializers.insert(mtpc_userFull, _serialize_userFull);
|
_serializers.insert(mtpc_userFull, _serialize_userFull);
|
||||||
_serializers.insert(mtpc_contact, _serialize_contact);
|
_serializers.insert(mtpc_contact, _serialize_contact);
|
||||||
_serializers.insert(mtpc_importedContact, _serialize_importedContact);
|
_serializers.insert(mtpc_importedContact, _serialize_importedContact);
|
||||||
|
@ -7372,6 +7484,9 @@ namespace {
|
||||||
_serializers.insert(mtpc_updateChannelMessageViews, _serialize_updateChannelMessageViews);
|
_serializers.insert(mtpc_updateChannelMessageViews, _serialize_updateChannelMessageViews);
|
||||||
_serializers.insert(mtpc_updateChatAdmins, _serialize_updateChatAdmins);
|
_serializers.insert(mtpc_updateChatAdmins, _serialize_updateChatAdmins);
|
||||||
_serializers.insert(mtpc_updateChatParticipantAdmin, _serialize_updateChatParticipantAdmin);
|
_serializers.insert(mtpc_updateChatParticipantAdmin, _serialize_updateChatParticipantAdmin);
|
||||||
|
_serializers.insert(mtpc_updateNewStickerSet, _serialize_updateNewStickerSet);
|
||||||
|
_serializers.insert(mtpc_updateStickerSetsOrder, _serialize_updateStickerSetsOrder);
|
||||||
|
_serializers.insert(mtpc_updateStickerSets, _serialize_updateStickerSets);
|
||||||
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
|
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
|
||||||
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
|
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
|
||||||
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
|
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
|
||||||
|
@ -7536,6 +7651,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_channelRoleEditor, _serialize_channelRoleEditor);
|
_serializers.insert(mtpc_channelRoleEditor, _serialize_channelRoleEditor);
|
||||||
_serializers.insert(mtpc_channels_channelParticipants, _serialize_channels_channelParticipants);
|
_serializers.insert(mtpc_channels_channelParticipants, _serialize_channels_channelParticipants);
|
||||||
_serializers.insert(mtpc_channels_channelParticipant, _serialize_channels_channelParticipant);
|
_serializers.insert(mtpc_channels_channelParticipant, _serialize_channels_channelParticipant);
|
||||||
|
_serializers.insert(mtpc_help_termsOfService, _serialize_help_termsOfService);
|
||||||
|
|
||||||
_serializers.insert(mtpc_req_pq, _serialize_req_pq);
|
_serializers.insert(mtpc_req_pq, _serialize_req_pq);
|
||||||
_serializers.insert(mtpc_req_DH_params, _serialize_req_DH_params);
|
_serializers.insert(mtpc_req_DH_params, _serialize_req_DH_params);
|
||||||
|
@ -7557,6 +7673,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_account_updateNotifySettings, _serialize_account_updateNotifySettings);
|
_serializers.insert(mtpc_account_updateNotifySettings, _serialize_account_updateNotifySettings);
|
||||||
_serializers.insert(mtpc_account_resetNotifySettings, _serialize_account_resetNotifySettings);
|
_serializers.insert(mtpc_account_resetNotifySettings, _serialize_account_resetNotifySettings);
|
||||||
_serializers.insert(mtpc_account_updateStatus, _serialize_account_updateStatus);
|
_serializers.insert(mtpc_account_updateStatus, _serialize_account_updateStatus);
|
||||||
|
_serializers.insert(mtpc_account_reportPeer, _serialize_account_reportPeer);
|
||||||
_serializers.insert(mtpc_account_checkUsername, _serialize_account_checkUsername);
|
_serializers.insert(mtpc_account_checkUsername, _serialize_account_checkUsername);
|
||||||
_serializers.insert(mtpc_account_deleteAccount, _serialize_account_deleteAccount);
|
_serializers.insert(mtpc_account_deleteAccount, _serialize_account_deleteAccount);
|
||||||
_serializers.insert(mtpc_account_setAccountTTL, _serialize_account_setAccountTTL);
|
_serializers.insert(mtpc_account_setAccountTTL, _serialize_account_setAccountTTL);
|
||||||
|
@ -7574,6 +7691,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_messages_installStickerSet, _serialize_messages_installStickerSet);
|
_serializers.insert(mtpc_messages_installStickerSet, _serialize_messages_installStickerSet);
|
||||||
_serializers.insert(mtpc_messages_uninstallStickerSet, _serialize_messages_uninstallStickerSet);
|
_serializers.insert(mtpc_messages_uninstallStickerSet, _serialize_messages_uninstallStickerSet);
|
||||||
_serializers.insert(mtpc_messages_editChatAdmin, _serialize_messages_editChatAdmin);
|
_serializers.insert(mtpc_messages_editChatAdmin, _serialize_messages_editChatAdmin);
|
||||||
|
_serializers.insert(mtpc_messages_reorderStickerSets, _serialize_messages_reorderStickerSets);
|
||||||
_serializers.insert(mtpc_upload_saveFilePart, _serialize_upload_saveFilePart);
|
_serializers.insert(mtpc_upload_saveFilePart, _serialize_upload_saveFilePart);
|
||||||
_serializers.insert(mtpc_upload_saveBigFilePart, _serialize_upload_saveBigFilePart);
|
_serializers.insert(mtpc_upload_saveBigFilePart, _serialize_upload_saveBigFilePart);
|
||||||
_serializers.insert(mtpc_help_saveAppLog, _serialize_help_saveAppLog);
|
_serializers.insert(mtpc_help_saveAppLog, _serialize_help_saveAppLog);
|
||||||
|
@ -7693,6 +7811,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_help_getInviteText, _serialize_help_getInviteText);
|
_serializers.insert(mtpc_help_getInviteText, _serialize_help_getInviteText);
|
||||||
_serializers.insert(mtpc_help_getSupport, _serialize_help_getSupport);
|
_serializers.insert(mtpc_help_getSupport, _serialize_help_getSupport);
|
||||||
_serializers.insert(mtpc_help_getAppChangelog, _serialize_help_getAppChangelog);
|
_serializers.insert(mtpc_help_getAppChangelog, _serialize_help_getAppChangelog);
|
||||||
|
_serializers.insert(mtpc_help_getTermsOfService, _serialize_help_getTermsOfService);
|
||||||
_serializers.insert(mtpc_channels_getParticipants, _serialize_channels_getParticipants);
|
_serializers.insert(mtpc_channels_getParticipants, _serialize_channels_getParticipants);
|
||||||
_serializers.insert(mtpc_channels_getParticipant, _serialize_channels_getParticipant);
|
_serializers.insert(mtpc_channels_getParticipant, _serialize_channels_getParticipant);
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,10 @@ enum {
|
||||||
mtpc_peerNotifySettings = 0x8d5e11ee,
|
mtpc_peerNotifySettings = 0x8d5e11ee,
|
||||||
mtpc_wallPaper = 0xccb03657,
|
mtpc_wallPaper = 0xccb03657,
|
||||||
mtpc_wallPaperSolid = 0x63117f24,
|
mtpc_wallPaperSolid = 0x63117f24,
|
||||||
|
mtpc_inputReportReasonSpam = 0x58dbcab8,
|
||||||
|
mtpc_inputReportReasonViolence = 0x1e22c78d,
|
||||||
|
mtpc_inputReportReasonPornography = 0x2e59d922,
|
||||||
|
mtpc_inputReportReasonOther = 0xe1746d0a,
|
||||||
mtpc_userFull = 0x5a89ac5b,
|
mtpc_userFull = 0x5a89ac5b,
|
||||||
mtpc_contact = 0xf911c994,
|
mtpc_contact = 0xf911c994,
|
||||||
mtpc_importedContact = 0xd0028438,
|
mtpc_importedContact = 0xd0028438,
|
||||||
|
@ -272,6 +276,9 @@ enum {
|
||||||
mtpc_updateChannelMessageViews = 0x98a12b4b,
|
mtpc_updateChannelMessageViews = 0x98a12b4b,
|
||||||
mtpc_updateChatAdmins = 0x6e947941,
|
mtpc_updateChatAdmins = 0x6e947941,
|
||||||
mtpc_updateChatParticipantAdmin = 0xb6901959,
|
mtpc_updateChatParticipantAdmin = 0xb6901959,
|
||||||
|
mtpc_updateNewStickerSet = 0x688a30aa,
|
||||||
|
mtpc_updateStickerSetsOrder = 0xf0dfb451,
|
||||||
|
mtpc_updateStickerSets = 0x43ae3dec,
|
||||||
mtpc_updates_state = 0xa56c2a3e,
|
mtpc_updates_state = 0xa56c2a3e,
|
||||||
mtpc_updates_differenceEmpty = 0x5d75a138,
|
mtpc_updates_differenceEmpty = 0x5d75a138,
|
||||||
mtpc_updates_difference = 0xf49ca0,
|
mtpc_updates_difference = 0xf49ca0,
|
||||||
|
@ -362,7 +369,7 @@ enum {
|
||||||
mtpc_messages_stickers = 0x8a8ecd32,
|
mtpc_messages_stickers = 0x8a8ecd32,
|
||||||
mtpc_stickerPack = 0x12b299d4,
|
mtpc_stickerPack = 0x12b299d4,
|
||||||
mtpc_messages_allStickersNotModified = 0xe86602c3,
|
mtpc_messages_allStickersNotModified = 0xe86602c3,
|
||||||
mtpc_messages_allStickers = 0xd51dafdb,
|
mtpc_messages_allStickers = 0xedfd405f,
|
||||||
mtpc_disabledFeature = 0xae636f24,
|
mtpc_disabledFeature = 0xae636f24,
|
||||||
mtpc_messages_affectedMessages = 0x84d19185,
|
mtpc_messages_affectedMessages = 0x84d19185,
|
||||||
mtpc_contactLinkUnknown = 0x5f4f9247,
|
mtpc_contactLinkUnknown = 0x5f4f9247,
|
||||||
|
@ -436,6 +443,7 @@ enum {
|
||||||
mtpc_channelRoleEditor = 0x820bfe8c,
|
mtpc_channelRoleEditor = 0x820bfe8c,
|
||||||
mtpc_channels_channelParticipants = 0xf56ee2a8,
|
mtpc_channels_channelParticipants = 0xf56ee2a8,
|
||||||
mtpc_channels_channelParticipant = 0xd0d9b163,
|
mtpc_channels_channelParticipant = 0xd0d9b163,
|
||||||
|
mtpc_help_termsOfService = 0xf1ee3e90,
|
||||||
mtpc_invokeAfterMsg = 0xcb9f372d,
|
mtpc_invokeAfterMsg = 0xcb9f372d,
|
||||||
mtpc_invokeAfterMsgs = 0x3dc4b4f0,
|
mtpc_invokeAfterMsgs = 0x3dc4b4f0,
|
||||||
mtpc_initConnection = 0x69796de9,
|
mtpc_initConnection = 0x69796de9,
|
||||||
|
@ -465,6 +473,7 @@ enum {
|
||||||
mtpc_account_updateProfile = 0xf0888d68,
|
mtpc_account_updateProfile = 0xf0888d68,
|
||||||
mtpc_account_updateStatus = 0x6628562c,
|
mtpc_account_updateStatus = 0x6628562c,
|
||||||
mtpc_account_getWallPapers = 0xc04cfac2,
|
mtpc_account_getWallPapers = 0xc04cfac2,
|
||||||
|
mtpc_account_reportPeer = 0xae189d5f,
|
||||||
mtpc_account_checkUsername = 0x2714d86c,
|
mtpc_account_checkUsername = 0x2714d86c,
|
||||||
mtpc_account_updateUsername = 0x3e0bdd7c,
|
mtpc_account_updateUsername = 0x3e0bdd7c,
|
||||||
mtpc_account_getPrivacy = 0xdadbc950,
|
mtpc_account_getPrivacy = 0xdadbc950,
|
||||||
|
@ -529,7 +538,7 @@ enum {
|
||||||
mtpc_messages_receivedQueue = 0x55a5bb66,
|
mtpc_messages_receivedQueue = 0x55a5bb66,
|
||||||
mtpc_messages_readMessageContents = 0x36a73f77,
|
mtpc_messages_readMessageContents = 0x36a73f77,
|
||||||
mtpc_messages_getStickers = 0xae22e045,
|
mtpc_messages_getStickers = 0xae22e045,
|
||||||
mtpc_messages_getAllStickers = 0xaa3bc868,
|
mtpc_messages_getAllStickers = 0x1c9618b1,
|
||||||
mtpc_messages_getWebPagePreview = 0x25223e24,
|
mtpc_messages_getWebPagePreview = 0x25223e24,
|
||||||
mtpc_messages_exportChatInvite = 0x7d885289,
|
mtpc_messages_exportChatInvite = 0x7d885289,
|
||||||
mtpc_messages_checkChatInvite = 0x3eadb1bb,
|
mtpc_messages_checkChatInvite = 0x3eadb1bb,
|
||||||
|
@ -543,6 +552,7 @@ enum {
|
||||||
mtpc_messages_editChatAdmin = 0xa9e69f2e,
|
mtpc_messages_editChatAdmin = 0xa9e69f2e,
|
||||||
mtpc_messages_migrateChat = 0x15a3b8e3,
|
mtpc_messages_migrateChat = 0x15a3b8e3,
|
||||||
mtpc_messages_searchGlobal = 0x9e3cacb0,
|
mtpc_messages_searchGlobal = 0x9e3cacb0,
|
||||||
|
mtpc_messages_reorderStickerSets = 0x9fcfbc30,
|
||||||
mtpc_updates_getState = 0xedd4882a,
|
mtpc_updates_getState = 0xedd4882a,
|
||||||
mtpc_updates_getDifference = 0xa041495,
|
mtpc_updates_getDifference = 0xa041495,
|
||||||
mtpc_updates_getChannelDifference = 0xbb32d7c0,
|
mtpc_updates_getChannelDifference = 0xbb32d7c0,
|
||||||
|
@ -560,6 +570,7 @@ enum {
|
||||||
mtpc_help_getInviteText = 0xa4a95186,
|
mtpc_help_getInviteText = 0xa4a95186,
|
||||||
mtpc_help_getSupport = 0x9cdf08cd,
|
mtpc_help_getSupport = 0x9cdf08cd,
|
||||||
mtpc_help_getAppChangelog = 0x5bab7fb2,
|
mtpc_help_getAppChangelog = 0x5bab7fb2,
|
||||||
|
mtpc_help_getTermsOfService = 0x37d78f83,
|
||||||
mtpc_channels_getDialogs = 0xa9d3d249,
|
mtpc_channels_getDialogs = 0xa9d3d249,
|
||||||
mtpc_channels_getImportantHistory = 0xddb929cb,
|
mtpc_channels_getImportantHistory = 0xddb929cb,
|
||||||
mtpc_channels_readHistory = 0xcc104937,
|
mtpc_channels_readHistory = 0xcc104937,
|
||||||
|
@ -843,6 +854,9 @@ class MTPwallPaper;
|
||||||
class MTPDwallPaper;
|
class MTPDwallPaper;
|
||||||
class MTPDwallPaperSolid;
|
class MTPDwallPaperSolid;
|
||||||
|
|
||||||
|
class MTPreportReason;
|
||||||
|
class MTPDinputReportReasonOther;
|
||||||
|
|
||||||
class MTPuserFull;
|
class MTPuserFull;
|
||||||
class MTPDuserFull;
|
class MTPDuserFull;
|
||||||
|
|
||||||
|
@ -935,6 +949,8 @@ class MTPDupdateDeleteChannelMessages;
|
||||||
class MTPDupdateChannelMessageViews;
|
class MTPDupdateChannelMessageViews;
|
||||||
class MTPDupdateChatAdmins;
|
class MTPDupdateChatAdmins;
|
||||||
class MTPDupdateChatParticipantAdmin;
|
class MTPDupdateChatParticipantAdmin;
|
||||||
|
class MTPDupdateNewStickerSet;
|
||||||
|
class MTPDupdateStickerSetsOrder;
|
||||||
|
|
||||||
class MTPupdates_state;
|
class MTPupdates_state;
|
||||||
class MTPDupdates_state;
|
class MTPDupdates_state;
|
||||||
|
@ -1196,6 +1212,9 @@ class MTPDchannels_channelParticipants;
|
||||||
class MTPchannels_channelParticipant;
|
class MTPchannels_channelParticipant;
|
||||||
class MTPDchannels_channelParticipant;
|
class MTPDchannels_channelParticipant;
|
||||||
|
|
||||||
|
class MTPhelp_termsOfService;
|
||||||
|
class MTPDhelp_termsOfService;
|
||||||
|
|
||||||
|
|
||||||
// Boxed types definitions
|
// Boxed types definitions
|
||||||
typedef MTPBoxed<MTPresPQ> MTPResPQ;
|
typedef MTPBoxed<MTPresPQ> MTPResPQ;
|
||||||
|
@ -1264,6 +1283,7 @@ typedef MTPBoxed<MTPinputPeerNotifySettings> MTPInputPeerNotifySettings;
|
||||||
typedef MTPBoxed<MTPpeerNotifyEvents> MTPPeerNotifyEvents;
|
typedef MTPBoxed<MTPpeerNotifyEvents> MTPPeerNotifyEvents;
|
||||||
typedef MTPBoxed<MTPpeerNotifySettings> MTPPeerNotifySettings;
|
typedef MTPBoxed<MTPpeerNotifySettings> MTPPeerNotifySettings;
|
||||||
typedef MTPBoxed<MTPwallPaper> MTPWallPaper;
|
typedef MTPBoxed<MTPwallPaper> MTPWallPaper;
|
||||||
|
typedef MTPBoxed<MTPreportReason> MTPReportReason;
|
||||||
typedef MTPBoxed<MTPuserFull> MTPUserFull;
|
typedef MTPBoxed<MTPuserFull> MTPUserFull;
|
||||||
typedef MTPBoxed<MTPcontact> MTPContact;
|
typedef MTPBoxed<MTPcontact> MTPContact;
|
||||||
typedef MTPBoxed<MTPimportedContact> MTPImportedContact;
|
typedef MTPBoxed<MTPimportedContact> MTPImportedContact;
|
||||||
|
@ -1353,6 +1373,7 @@ typedef MTPBoxed<MTPchannelParticipantsFilter> MTPChannelParticipantsFilter;
|
||||||
typedef MTPBoxed<MTPchannelParticipantRole> MTPChannelParticipantRole;
|
typedef MTPBoxed<MTPchannelParticipantRole> MTPChannelParticipantRole;
|
||||||
typedef MTPBoxed<MTPchannels_channelParticipants> MTPchannels_ChannelParticipants;
|
typedef MTPBoxed<MTPchannels_channelParticipants> MTPchannels_ChannelParticipants;
|
||||||
typedef MTPBoxed<MTPchannels_channelParticipant> MTPchannels_ChannelParticipant;
|
typedef MTPBoxed<MTPchannels_channelParticipant> MTPchannels_ChannelParticipant;
|
||||||
|
typedef MTPBoxed<MTPhelp_termsOfService> MTPhelp_TermsOfService;
|
||||||
|
|
||||||
// Type classes definitions
|
// Type classes definitions
|
||||||
|
|
||||||
|
@ -4503,6 +4524,46 @@ private:
|
||||||
};
|
};
|
||||||
typedef MTPBoxed<MTPwallPaper> MTPWallPaper;
|
typedef MTPBoxed<MTPwallPaper> MTPWallPaper;
|
||||||
|
|
||||||
|
class MTPreportReason : private mtpDataOwner {
|
||||||
|
public:
|
||||||
|
MTPreportReason() : mtpDataOwner(0), _type(0) {
|
||||||
|
}
|
||||||
|
MTPreportReason(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
|
||||||
|
read(from, end, cons);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPDinputReportReasonOther &_inputReportReasonOther() {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
if (_type != mtpc_inputReportReasonOther) throw mtpErrorWrongTypeId(_type, mtpc_inputReportReasonOther);
|
||||||
|
split();
|
||||||
|
return *(MTPDinputReportReasonOther*)data;
|
||||||
|
}
|
||||||
|
const MTPDinputReportReasonOther &c_inputReportReasonOther() const {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
if (_type != mtpc_inputReportReasonOther) throw mtpErrorWrongTypeId(_type, mtpc_inputReportReasonOther);
|
||||||
|
return *(const MTPDinputReportReasonOther*)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 innerLength() const;
|
||||||
|
mtpTypeId type() const;
|
||||||
|
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
|
||||||
|
void write(mtpBuffer &to) const;
|
||||||
|
|
||||||
|
typedef void ResponseType;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit MTPreportReason(mtpTypeId type);
|
||||||
|
explicit MTPreportReason(MTPDinputReportReasonOther *_data);
|
||||||
|
|
||||||
|
friend MTPreportReason MTP_inputReportReasonSpam();
|
||||||
|
friend MTPreportReason MTP_inputReportReasonViolence();
|
||||||
|
friend MTPreportReason MTP_inputReportReasonPornography();
|
||||||
|
friend MTPreportReason MTP_inputReportReasonOther(const MTPstring &_text);
|
||||||
|
|
||||||
|
mtpTypeId _type;
|
||||||
|
};
|
||||||
|
typedef MTPBoxed<MTPreportReason> MTPReportReason;
|
||||||
|
|
||||||
class MTPuserFull : private mtpDataOwner {
|
class MTPuserFull : private mtpDataOwner {
|
||||||
public:
|
public:
|
||||||
MTPuserFull();
|
MTPuserFull();
|
||||||
|
@ -5564,6 +5625,30 @@ public:
|
||||||
return *(const MTPDupdateChatParticipantAdmin*)data;
|
return *(const MTPDupdateChatParticipantAdmin*)data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTPDupdateNewStickerSet &_updateNewStickerSet() {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
if (_type != mtpc_updateNewStickerSet) throw mtpErrorWrongTypeId(_type, mtpc_updateNewStickerSet);
|
||||||
|
split();
|
||||||
|
return *(MTPDupdateNewStickerSet*)data;
|
||||||
|
}
|
||||||
|
const MTPDupdateNewStickerSet &c_updateNewStickerSet() const {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
if (_type != mtpc_updateNewStickerSet) throw mtpErrorWrongTypeId(_type, mtpc_updateNewStickerSet);
|
||||||
|
return *(const MTPDupdateNewStickerSet*)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPDupdateStickerSetsOrder &_updateStickerSetsOrder() {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
if (_type != mtpc_updateStickerSetsOrder) throw mtpErrorWrongTypeId(_type, mtpc_updateStickerSetsOrder);
|
||||||
|
split();
|
||||||
|
return *(MTPDupdateStickerSetsOrder*)data;
|
||||||
|
}
|
||||||
|
const MTPDupdateStickerSetsOrder &c_updateStickerSetsOrder() const {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
if (_type != mtpc_updateStickerSetsOrder) throw mtpErrorWrongTypeId(_type, mtpc_updateStickerSetsOrder);
|
||||||
|
return *(const MTPDupdateStickerSetsOrder*)data;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 innerLength() const;
|
uint32 innerLength() const;
|
||||||
mtpTypeId type() const;
|
mtpTypeId type() const;
|
||||||
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
|
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
|
||||||
|
@ -5610,6 +5695,8 @@ private:
|
||||||
explicit MTPupdate(MTPDupdateChannelMessageViews *_data);
|
explicit MTPupdate(MTPDupdateChannelMessageViews *_data);
|
||||||
explicit MTPupdate(MTPDupdateChatAdmins *_data);
|
explicit MTPupdate(MTPDupdateChatAdmins *_data);
|
||||||
explicit MTPupdate(MTPDupdateChatParticipantAdmin *_data);
|
explicit MTPupdate(MTPDupdateChatParticipantAdmin *_data);
|
||||||
|
explicit MTPupdate(MTPDupdateNewStickerSet *_data);
|
||||||
|
explicit MTPupdate(MTPDupdateStickerSetsOrder *_data);
|
||||||
|
|
||||||
friend MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count);
|
friend MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count);
|
||||||
friend MTPupdate MTP_updateMessageID(MTPint _id, const MTPlong &_random_id);
|
friend MTPupdate MTP_updateMessageID(MTPint _id, const MTPlong &_random_id);
|
||||||
|
@ -5648,6 +5735,9 @@ private:
|
||||||
friend MTPupdate MTP_updateChannelMessageViews(MTPint _channel_id, MTPint _id, MTPint _views);
|
friend MTPupdate MTP_updateChannelMessageViews(MTPint _channel_id, MTPint _id, MTPint _views);
|
||||||
friend MTPupdate MTP_updateChatAdmins(MTPint _chat_id, MTPBool _enabled, MTPint _version);
|
friend MTPupdate MTP_updateChatAdmins(MTPint _chat_id, MTPBool _enabled, MTPint _version);
|
||||||
friend MTPupdate MTP_updateChatParticipantAdmin(MTPint _chat_id, MTPint _user_id, MTPBool _is_admin, MTPint _version);
|
friend MTPupdate MTP_updateChatParticipantAdmin(MTPint _chat_id, MTPint _user_id, MTPBool _is_admin, MTPint _version);
|
||||||
|
friend MTPupdate MTP_updateNewStickerSet(const MTPmessages_StickerSet &_stickerset);
|
||||||
|
friend MTPupdate MTP_updateStickerSetsOrder(const MTPVector<MTPlong> &_order);
|
||||||
|
friend MTPupdate MTP_updateStickerSets();
|
||||||
|
|
||||||
mtpTypeId _type;
|
mtpTypeId _type;
|
||||||
};
|
};
|
||||||
|
@ -7318,7 +7408,7 @@ private:
|
||||||
explicit MTPmessages_allStickers(MTPDmessages_allStickers *_data);
|
explicit MTPmessages_allStickers(MTPDmessages_allStickers *_data);
|
||||||
|
|
||||||
friend MTPmessages_allStickers MTP_messages_allStickersNotModified();
|
friend MTPmessages_allStickers MTP_messages_allStickersNotModified();
|
||||||
friend MTPmessages_allStickers MTP_messages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerSet> &_sets);
|
friend MTPmessages_allStickers MTP_messages_allStickers(MTPint _hash, const MTPVector<MTPStickerSet> &_sets);
|
||||||
|
|
||||||
mtpTypeId _type;
|
mtpTypeId _type;
|
||||||
};
|
};
|
||||||
|
@ -8786,6 +8876,37 @@ private:
|
||||||
};
|
};
|
||||||
typedef MTPBoxed<MTPchannels_channelParticipant> MTPchannels_ChannelParticipant;
|
typedef MTPBoxed<MTPchannels_channelParticipant> MTPchannels_ChannelParticipant;
|
||||||
|
|
||||||
|
class MTPhelp_termsOfService : private mtpDataOwner {
|
||||||
|
public:
|
||||||
|
MTPhelp_termsOfService();
|
||||||
|
MTPhelp_termsOfService(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_help_termsOfService) : mtpDataOwner(0) {
|
||||||
|
read(from, end, cons);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPDhelp_termsOfService &_help_termsOfService() {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
split();
|
||||||
|
return *(MTPDhelp_termsOfService*)data;
|
||||||
|
}
|
||||||
|
const MTPDhelp_termsOfService &c_help_termsOfService() const {
|
||||||
|
if (!data) throw mtpErrorUninitialized();
|
||||||
|
return *(const MTPDhelp_termsOfService*)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 innerLength() const;
|
||||||
|
mtpTypeId type() const;
|
||||||
|
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_help_termsOfService);
|
||||||
|
void write(mtpBuffer &to) const;
|
||||||
|
|
||||||
|
typedef void ResponseType;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit MTPhelp_termsOfService(MTPDhelp_termsOfService *_data);
|
||||||
|
|
||||||
|
friend MTPhelp_termsOfService MTP_help_termsOfService(const MTPstring &_text);
|
||||||
|
};
|
||||||
|
typedef MTPBoxed<MTPhelp_termsOfService> MTPhelp_TermsOfService;
|
||||||
|
|
||||||
// Type constructors with data
|
// Type constructors with data
|
||||||
|
|
||||||
class MTPDresPQ : public mtpDataImpl<MTPDresPQ> {
|
class MTPDresPQ : public mtpDataImpl<MTPDresPQ> {
|
||||||
|
@ -10403,6 +10524,16 @@ public:
|
||||||
MTPint vcolor;
|
MTPint vcolor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MTPDinputReportReasonOther : public mtpDataImpl<MTPDinputReportReasonOther> {
|
||||||
|
public:
|
||||||
|
MTPDinputReportReasonOther() {
|
||||||
|
}
|
||||||
|
MTPDinputReportReasonOther(const MTPstring &_text) : vtext(_text) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPstring vtext;
|
||||||
|
};
|
||||||
|
|
||||||
class MTPDuserFull : public mtpDataImpl<MTPDuserFull> {
|
class MTPDuserFull : public mtpDataImpl<MTPDuserFull> {
|
||||||
public:
|
public:
|
||||||
MTPDuserFull() {
|
MTPDuserFull() {
|
||||||
|
@ -11082,6 +11213,26 @@ public:
|
||||||
MTPint vversion;
|
MTPint vversion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MTPDupdateNewStickerSet : public mtpDataImpl<MTPDupdateNewStickerSet> {
|
||||||
|
public:
|
||||||
|
MTPDupdateNewStickerSet() {
|
||||||
|
}
|
||||||
|
MTPDupdateNewStickerSet(const MTPmessages_StickerSet &_stickerset) : vstickerset(_stickerset) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPmessages_StickerSet vstickerset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MTPDupdateStickerSetsOrder : public mtpDataImpl<MTPDupdateStickerSetsOrder> {
|
||||||
|
public:
|
||||||
|
MTPDupdateStickerSetsOrder() {
|
||||||
|
}
|
||||||
|
MTPDupdateStickerSetsOrder(const MTPVector<MTPlong> &_order) : vorder(_order) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPVector<MTPlong> vorder;
|
||||||
|
};
|
||||||
|
|
||||||
class MTPDupdates_state : public mtpDataImpl<MTPDupdates_state> {
|
class MTPDupdates_state : public mtpDataImpl<MTPDupdates_state> {
|
||||||
public:
|
public:
|
||||||
MTPDupdates_state() {
|
MTPDupdates_state() {
|
||||||
|
@ -11914,10 +12065,10 @@ class MTPDmessages_allStickers : public mtpDataImpl<MTPDmessages_allStickers> {
|
||||||
public:
|
public:
|
||||||
MTPDmessages_allStickers() {
|
MTPDmessages_allStickers() {
|
||||||
}
|
}
|
||||||
MTPDmessages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerSet> &_sets) : vhash(_hash), vsets(_sets) {
|
MTPDmessages_allStickers(MTPint _hash, const MTPVector<MTPStickerSet> &_sets) : vhash(_hash), vsets(_sets) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MTPstring vhash;
|
MTPint vhash;
|
||||||
MTPVector<MTPStickerSet> vsets;
|
MTPVector<MTPStickerSet> vsets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12696,6 +12847,16 @@ public:
|
||||||
MTPVector<MTPUser> vusers;
|
MTPVector<MTPUser> vusers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MTPDhelp_termsOfService : public mtpDataImpl<MTPDhelp_termsOfService> {
|
||||||
|
public:
|
||||||
|
MTPDhelp_termsOfService() {
|
||||||
|
}
|
||||||
|
MTPDhelp_termsOfService(const MTPstring &_text) : vtext(_text) {
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPstring vtext;
|
||||||
|
};
|
||||||
|
|
||||||
// RPC methods
|
// RPC methods
|
||||||
|
|
||||||
class MTPreq_pq { // RPC method 'req_pq'
|
class MTPreq_pq { // RPC method 'req_pq'
|
||||||
|
@ -14287,6 +14448,48 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MTPaccount_reportPeer { // RPC method 'account.reportPeer'
|
||||||
|
public:
|
||||||
|
MTPInputPeer vpeer;
|
||||||
|
MTPReportReason vreason;
|
||||||
|
|
||||||
|
MTPaccount_reportPeer() {
|
||||||
|
}
|
||||||
|
MTPaccount_reportPeer(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_reportPeer) {
|
||||||
|
read(from, end, cons);
|
||||||
|
}
|
||||||
|
MTPaccount_reportPeer(const MTPInputPeer &_peer, const MTPReportReason &_reason) : vpeer(_peer), vreason(_reason) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 innerLength() const {
|
||||||
|
return vpeer.innerLength() + vreason.innerLength();
|
||||||
|
}
|
||||||
|
mtpTypeId type() const {
|
||||||
|
return mtpc_account_reportPeer;
|
||||||
|
}
|
||||||
|
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_account_reportPeer) {
|
||||||
|
vpeer.read(from, end);
|
||||||
|
vreason.read(from, end);
|
||||||
|
}
|
||||||
|
void write(mtpBuffer &to) const {
|
||||||
|
vpeer.write(to);
|
||||||
|
vreason.write(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef MTPBool ResponseType;
|
||||||
|
};
|
||||||
|
class MTPaccount_ReportPeer : public MTPBoxed<MTPaccount_reportPeer> {
|
||||||
|
public:
|
||||||
|
MTPaccount_ReportPeer() {
|
||||||
|
}
|
||||||
|
MTPaccount_ReportPeer(const MTPaccount_reportPeer &v) : MTPBoxed<MTPaccount_reportPeer>(v) {
|
||||||
|
}
|
||||||
|
MTPaccount_ReportPeer(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPaccount_reportPeer>(from, end, cons) {
|
||||||
|
}
|
||||||
|
MTPaccount_ReportPeer(const MTPInputPeer &_peer, const MTPReportReason &_reason) : MTPBoxed<MTPaccount_reportPeer>(MTPaccount_reportPeer(_peer, _reason)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class MTPaccount_checkUsername { // RPC method 'account.checkUsername'
|
class MTPaccount_checkUsername { // RPC method 'account.checkUsername'
|
||||||
public:
|
public:
|
||||||
MTPstring vusername;
|
MTPstring vusername;
|
||||||
|
@ -16982,14 +17185,14 @@ public:
|
||||||
|
|
||||||
class MTPmessages_getAllStickers { // RPC method 'messages.getAllStickers'
|
class MTPmessages_getAllStickers { // RPC method 'messages.getAllStickers'
|
||||||
public:
|
public:
|
||||||
MTPstring vhash;
|
MTPint vhash;
|
||||||
|
|
||||||
MTPmessages_getAllStickers() {
|
MTPmessages_getAllStickers() {
|
||||||
}
|
}
|
||||||
MTPmessages_getAllStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getAllStickers) {
|
MTPmessages_getAllStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getAllStickers) {
|
||||||
read(from, end, cons);
|
read(from, end, cons);
|
||||||
}
|
}
|
||||||
MTPmessages_getAllStickers(const MTPstring &_hash) : vhash(_hash) {
|
MTPmessages_getAllStickers(MTPint _hash) : vhash(_hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 innerLength() const {
|
uint32 innerLength() const {
|
||||||
|
@ -17015,7 +17218,7 @@ public:
|
||||||
}
|
}
|
||||||
MTPmessages_GetAllStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_getAllStickers>(from, end, cons) {
|
MTPmessages_GetAllStickers(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_getAllStickers>(from, end, cons) {
|
||||||
}
|
}
|
||||||
MTPmessages_GetAllStickers(const MTPstring &_hash) : MTPBoxed<MTPmessages_getAllStickers>(MTPmessages_getAllStickers(_hash)) {
|
MTPmessages_GetAllStickers(MTPint _hash) : MTPBoxed<MTPmessages_getAllStickers>(MTPmessages_getAllStickers(_hash)) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17565,6 +17768,45 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MTPmessages_reorderStickerSets { // RPC method 'messages.reorderStickerSets'
|
||||||
|
public:
|
||||||
|
MTPVector<MTPlong> vorder;
|
||||||
|
|
||||||
|
MTPmessages_reorderStickerSets() {
|
||||||
|
}
|
||||||
|
MTPmessages_reorderStickerSets(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_reorderStickerSets) {
|
||||||
|
read(from, end, cons);
|
||||||
|
}
|
||||||
|
MTPmessages_reorderStickerSets(const MTPVector<MTPlong> &_order) : vorder(_order) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 innerLength() const {
|
||||||
|
return vorder.innerLength();
|
||||||
|
}
|
||||||
|
mtpTypeId type() const {
|
||||||
|
return mtpc_messages_reorderStickerSets;
|
||||||
|
}
|
||||||
|
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_reorderStickerSets) {
|
||||||
|
vorder.read(from, end);
|
||||||
|
}
|
||||||
|
void write(mtpBuffer &to) const {
|
||||||
|
vorder.write(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef MTPBool ResponseType;
|
||||||
|
};
|
||||||
|
class MTPmessages_ReorderStickerSets : public MTPBoxed<MTPmessages_reorderStickerSets> {
|
||||||
|
public:
|
||||||
|
MTPmessages_ReorderStickerSets() {
|
||||||
|
}
|
||||||
|
MTPmessages_ReorderStickerSets(const MTPmessages_reorderStickerSets &v) : MTPBoxed<MTPmessages_reorderStickerSets>(v) {
|
||||||
|
}
|
||||||
|
MTPmessages_ReorderStickerSets(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_reorderStickerSets>(from, end, cons) {
|
||||||
|
}
|
||||||
|
MTPmessages_ReorderStickerSets(const MTPVector<MTPlong> &_order) : MTPBoxed<MTPmessages_reorderStickerSets>(MTPmessages_reorderStickerSets(_order)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class MTPupdates_getState { // RPC method 'updates.getState'
|
class MTPupdates_getState { // RPC method 'updates.getState'
|
||||||
public:
|
public:
|
||||||
MTPupdates_getState() {
|
MTPupdates_getState() {
|
||||||
|
@ -18271,6 +18513,45 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MTPhelp_getTermsOfService { // RPC method 'help.getTermsOfService'
|
||||||
|
public:
|
||||||
|
MTPstring vlang_code;
|
||||||
|
|
||||||
|
MTPhelp_getTermsOfService() {
|
||||||
|
}
|
||||||
|
MTPhelp_getTermsOfService(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_help_getTermsOfService) {
|
||||||
|
read(from, end, cons);
|
||||||
|
}
|
||||||
|
MTPhelp_getTermsOfService(const MTPstring &_lang_code) : vlang_code(_lang_code) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 innerLength() const {
|
||||||
|
return vlang_code.innerLength();
|
||||||
|
}
|
||||||
|
mtpTypeId type() const {
|
||||||
|
return mtpc_help_getTermsOfService;
|
||||||
|
}
|
||||||
|
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_help_getTermsOfService) {
|
||||||
|
vlang_code.read(from, end);
|
||||||
|
}
|
||||||
|
void write(mtpBuffer &to) const {
|
||||||
|
vlang_code.write(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef MTPhelp_TermsOfService ResponseType;
|
||||||
|
};
|
||||||
|
class MTPhelp_GetTermsOfService : public MTPBoxed<MTPhelp_getTermsOfService> {
|
||||||
|
public:
|
||||||
|
MTPhelp_GetTermsOfService() {
|
||||||
|
}
|
||||||
|
MTPhelp_GetTermsOfService(const MTPhelp_getTermsOfService &v) : MTPBoxed<MTPhelp_getTermsOfService>(v) {
|
||||||
|
}
|
||||||
|
MTPhelp_GetTermsOfService(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPhelp_getTermsOfService>(from, end, cons) {
|
||||||
|
}
|
||||||
|
MTPhelp_GetTermsOfService(const MTPstring &_lang_code) : MTPBoxed<MTPhelp_getTermsOfService>(MTPhelp_getTermsOfService(_lang_code)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class MTPchannels_getDialogs { // RPC method 'channels.getDialogs'
|
class MTPchannels_getDialogs { // RPC method 'channels.getDialogs'
|
||||||
public:
|
public:
|
||||||
MTPint voffset;
|
MTPint voffset;
|
||||||
|
@ -23627,6 +23908,65 @@ inline MTPwallPaper MTP_wallPaperSolid(MTPint _id, const MTPstring &_title, MTPi
|
||||||
return MTPwallPaper(new MTPDwallPaperSolid(_id, _title, _bg_color, _color));
|
return MTPwallPaper(new MTPDwallPaperSolid(_id, _title, _bg_color, _color));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint32 MTPreportReason::innerLength() const {
|
||||||
|
switch (_type) {
|
||||||
|
case mtpc_inputReportReasonOther: {
|
||||||
|
const MTPDinputReportReasonOther &v(c_inputReportReasonOther());
|
||||||
|
return v.vtext.innerLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
inline mtpTypeId MTPreportReason::type() const {
|
||||||
|
if (!_type) throw mtpErrorUninitialized();
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
inline void MTPreportReason::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
|
||||||
|
if (cons != _type) setData(0);
|
||||||
|
switch (cons) {
|
||||||
|
case mtpc_inputReportReasonSpam: _type = cons; break;
|
||||||
|
case mtpc_inputReportReasonViolence: _type = cons; break;
|
||||||
|
case mtpc_inputReportReasonPornography: _type = cons; break;
|
||||||
|
case mtpc_inputReportReasonOther: _type = cons; {
|
||||||
|
if (!data) setData(new MTPDinputReportReasonOther());
|
||||||
|
MTPDinputReportReasonOther &v(_inputReportReasonOther());
|
||||||
|
v.vtext.read(from, end);
|
||||||
|
} break;
|
||||||
|
default: throw mtpErrorUnexpected(cons, "MTPreportReason");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void MTPreportReason::write(mtpBuffer &to) const {
|
||||||
|
switch (_type) {
|
||||||
|
case mtpc_inputReportReasonOther: {
|
||||||
|
const MTPDinputReportReasonOther &v(c_inputReportReasonOther());
|
||||||
|
v.vtext.write(to);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline MTPreportReason::MTPreportReason(mtpTypeId type) : mtpDataOwner(0), _type(type) {
|
||||||
|
switch (type) {
|
||||||
|
case mtpc_inputReportReasonSpam: break;
|
||||||
|
case mtpc_inputReportReasonViolence: break;
|
||||||
|
case mtpc_inputReportReasonPornography: break;
|
||||||
|
case mtpc_inputReportReasonOther: setData(new MTPDinputReportReasonOther()); break;
|
||||||
|
default: throw mtpErrorBadTypeId(type, "MTPreportReason");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline MTPreportReason::MTPreportReason(MTPDinputReportReasonOther *_data) : mtpDataOwner(_data), _type(mtpc_inputReportReasonOther) {
|
||||||
|
}
|
||||||
|
inline MTPreportReason MTP_inputReportReasonSpam() {
|
||||||
|
return MTPreportReason(mtpc_inputReportReasonSpam);
|
||||||
|
}
|
||||||
|
inline MTPreportReason MTP_inputReportReasonViolence() {
|
||||||
|
return MTPreportReason(mtpc_inputReportReasonViolence);
|
||||||
|
}
|
||||||
|
inline MTPreportReason MTP_inputReportReasonPornography() {
|
||||||
|
return MTPreportReason(mtpc_inputReportReasonPornography);
|
||||||
|
}
|
||||||
|
inline MTPreportReason MTP_inputReportReasonOther(const MTPstring &_text) {
|
||||||
|
return MTPreportReason(new MTPDinputReportReasonOther(_text));
|
||||||
|
}
|
||||||
|
|
||||||
inline MTPuserFull::MTPuserFull() : mtpDataOwner(new MTPDuserFull()) {
|
inline MTPuserFull::MTPuserFull() : mtpDataOwner(new MTPDuserFull()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24507,6 +24847,14 @@ inline uint32 MTPupdate::innerLength() const {
|
||||||
const MTPDupdateChatParticipantAdmin &v(c_updateChatParticipantAdmin());
|
const MTPDupdateChatParticipantAdmin &v(c_updateChatParticipantAdmin());
|
||||||
return v.vchat_id.innerLength() + v.vuser_id.innerLength() + v.vis_admin.innerLength() + v.vversion.innerLength();
|
return v.vchat_id.innerLength() + v.vuser_id.innerLength() + v.vis_admin.innerLength() + v.vversion.innerLength();
|
||||||
}
|
}
|
||||||
|
case mtpc_updateNewStickerSet: {
|
||||||
|
const MTPDupdateNewStickerSet &v(c_updateNewStickerSet());
|
||||||
|
return v.vstickerset.innerLength();
|
||||||
|
}
|
||||||
|
case mtpc_updateStickerSetsOrder: {
|
||||||
|
const MTPDupdateStickerSetsOrder &v(c_updateStickerSetsOrder());
|
||||||
|
return v.vorder.innerLength();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -24764,6 +25112,17 @@ inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeI
|
||||||
v.vis_admin.read(from, end);
|
v.vis_admin.read(from, end);
|
||||||
v.vversion.read(from, end);
|
v.vversion.read(from, end);
|
||||||
} break;
|
} break;
|
||||||
|
case mtpc_updateNewStickerSet: _type = cons; {
|
||||||
|
if (!data) setData(new MTPDupdateNewStickerSet());
|
||||||
|
MTPDupdateNewStickerSet &v(_updateNewStickerSet());
|
||||||
|
v.vstickerset.read(from, end);
|
||||||
|
} break;
|
||||||
|
case mtpc_updateStickerSetsOrder: _type = cons; {
|
||||||
|
if (!data) setData(new MTPDupdateStickerSetsOrder());
|
||||||
|
MTPDupdateStickerSetsOrder &v(_updateStickerSetsOrder());
|
||||||
|
v.vorder.read(from, end);
|
||||||
|
} break;
|
||||||
|
case mtpc_updateStickerSets: _type = cons; break;
|
||||||
default: throw mtpErrorUnexpected(cons, "MTPupdate");
|
default: throw mtpErrorUnexpected(cons, "MTPupdate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24979,6 +25338,14 @@ inline void MTPupdate::write(mtpBuffer &to) const {
|
||||||
v.vis_admin.write(to);
|
v.vis_admin.write(to);
|
||||||
v.vversion.write(to);
|
v.vversion.write(to);
|
||||||
} break;
|
} break;
|
||||||
|
case mtpc_updateNewStickerSet: {
|
||||||
|
const MTPDupdateNewStickerSet &v(c_updateNewStickerSet());
|
||||||
|
v.vstickerset.write(to);
|
||||||
|
} break;
|
||||||
|
case mtpc_updateStickerSetsOrder: {
|
||||||
|
const MTPDupdateStickerSetsOrder &v(c_updateStickerSetsOrder());
|
||||||
|
v.vorder.write(to);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
|
inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
|
||||||
|
@ -25020,6 +25387,9 @@ inline MTPupdate::MTPupdate(mtpTypeId type) : mtpDataOwner(0), _type(type) {
|
||||||
case mtpc_updateChannelMessageViews: setData(new MTPDupdateChannelMessageViews()); break;
|
case mtpc_updateChannelMessageViews: setData(new MTPDupdateChannelMessageViews()); break;
|
||||||
case mtpc_updateChatAdmins: setData(new MTPDupdateChatAdmins()); break;
|
case mtpc_updateChatAdmins: setData(new MTPDupdateChatAdmins()); break;
|
||||||
case mtpc_updateChatParticipantAdmin: setData(new MTPDupdateChatParticipantAdmin()); break;
|
case mtpc_updateChatParticipantAdmin: setData(new MTPDupdateChatParticipantAdmin()); break;
|
||||||
|
case mtpc_updateNewStickerSet: setData(new MTPDupdateNewStickerSet()); break;
|
||||||
|
case mtpc_updateStickerSetsOrder: setData(new MTPDupdateStickerSetsOrder()); break;
|
||||||
|
case mtpc_updateStickerSets: break;
|
||||||
default: throw mtpErrorBadTypeId(type, "MTPupdate");
|
default: throw mtpErrorBadTypeId(type, "MTPupdate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25097,6 +25467,10 @@ inline MTPupdate::MTPupdate(MTPDupdateChatAdmins *_data) : mtpDataOwner(_data),
|
||||||
}
|
}
|
||||||
inline MTPupdate::MTPupdate(MTPDupdateChatParticipantAdmin *_data) : mtpDataOwner(_data), _type(mtpc_updateChatParticipantAdmin) {
|
inline MTPupdate::MTPupdate(MTPDupdateChatParticipantAdmin *_data) : mtpDataOwner(_data), _type(mtpc_updateChatParticipantAdmin) {
|
||||||
}
|
}
|
||||||
|
inline MTPupdate::MTPupdate(MTPDupdateNewStickerSet *_data) : mtpDataOwner(_data), _type(mtpc_updateNewStickerSet) {
|
||||||
|
}
|
||||||
|
inline MTPupdate::MTPupdate(MTPDupdateStickerSetsOrder *_data) : mtpDataOwner(_data), _type(mtpc_updateStickerSetsOrder) {
|
||||||
|
}
|
||||||
inline MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) {
|
inline MTPupdate MTP_updateNewMessage(const MTPMessage &_message, MTPint _pts, MTPint _pts_count) {
|
||||||
return MTPupdate(new MTPDupdateNewMessage(_message, _pts, _pts_count));
|
return MTPupdate(new MTPDupdateNewMessage(_message, _pts, _pts_count));
|
||||||
}
|
}
|
||||||
|
@ -25208,6 +25582,15 @@ inline MTPupdate MTP_updateChatAdmins(MTPint _chat_id, MTPBool _enabled, MTPint
|
||||||
inline MTPupdate MTP_updateChatParticipantAdmin(MTPint _chat_id, MTPint _user_id, MTPBool _is_admin, MTPint _version) {
|
inline MTPupdate MTP_updateChatParticipantAdmin(MTPint _chat_id, MTPint _user_id, MTPBool _is_admin, MTPint _version) {
|
||||||
return MTPupdate(new MTPDupdateChatParticipantAdmin(_chat_id, _user_id, _is_admin, _version));
|
return MTPupdate(new MTPDupdateChatParticipantAdmin(_chat_id, _user_id, _is_admin, _version));
|
||||||
}
|
}
|
||||||
|
inline MTPupdate MTP_updateNewStickerSet(const MTPmessages_StickerSet &_stickerset) {
|
||||||
|
return MTPupdate(new MTPDupdateNewStickerSet(_stickerset));
|
||||||
|
}
|
||||||
|
inline MTPupdate MTP_updateStickerSetsOrder(const MTPVector<MTPlong> &_order) {
|
||||||
|
return MTPupdate(new MTPDupdateStickerSetsOrder(_order));
|
||||||
|
}
|
||||||
|
inline MTPupdate MTP_updateStickerSets() {
|
||||||
|
return MTPupdate(mtpc_updateStickerSets);
|
||||||
|
}
|
||||||
|
|
||||||
inline MTPupdates_state::MTPupdates_state() : mtpDataOwner(new MTPDupdates_state()) {
|
inline MTPupdates_state::MTPupdates_state() : mtpDataOwner(new MTPDupdates_state()) {
|
||||||
}
|
}
|
||||||
|
@ -27495,7 +27878,7 @@ inline MTPmessages_allStickers::MTPmessages_allStickers(MTPDmessages_allStickers
|
||||||
inline MTPmessages_allStickers MTP_messages_allStickersNotModified() {
|
inline MTPmessages_allStickers MTP_messages_allStickersNotModified() {
|
||||||
return MTPmessages_allStickers(mtpc_messages_allStickersNotModified);
|
return MTPmessages_allStickers(mtpc_messages_allStickersNotModified);
|
||||||
}
|
}
|
||||||
inline MTPmessages_allStickers MTP_messages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerSet> &_sets) {
|
inline MTPmessages_allStickers MTP_messages_allStickers(MTPint _hash, const MTPVector<MTPStickerSet> &_sets) {
|
||||||
return MTPmessages_allStickers(new MTPDmessages_allStickers(_hash, _sets));
|
return MTPmessages_allStickers(new MTPDmessages_allStickers(_hash, _sets));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29383,6 +29766,33 @@ inline MTPchannels_channelParticipant MTP_channels_channelParticipant(const MTPC
|
||||||
return MTPchannels_channelParticipant(new MTPDchannels_channelParticipant(_participant, _users));
|
return MTPchannels_channelParticipant(new MTPDchannels_channelParticipant(_participant, _users));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline MTPhelp_termsOfService::MTPhelp_termsOfService() : mtpDataOwner(new MTPDhelp_termsOfService()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32 MTPhelp_termsOfService::innerLength() const {
|
||||||
|
const MTPDhelp_termsOfService &v(c_help_termsOfService());
|
||||||
|
return v.vtext.innerLength();
|
||||||
|
}
|
||||||
|
inline mtpTypeId MTPhelp_termsOfService::type() const {
|
||||||
|
return mtpc_help_termsOfService;
|
||||||
|
}
|
||||||
|
inline void MTPhelp_termsOfService::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
|
||||||
|
if (cons != mtpc_help_termsOfService) throw mtpErrorUnexpected(cons, "MTPhelp_termsOfService");
|
||||||
|
|
||||||
|
if (!data) setData(new MTPDhelp_termsOfService());
|
||||||
|
MTPDhelp_termsOfService &v(_help_termsOfService());
|
||||||
|
v.vtext.read(from, end);
|
||||||
|
}
|
||||||
|
inline void MTPhelp_termsOfService::write(mtpBuffer &to) const {
|
||||||
|
const MTPDhelp_termsOfService &v(c_help_termsOfService());
|
||||||
|
v.vtext.write(to);
|
||||||
|
}
|
||||||
|
inline MTPhelp_termsOfService::MTPhelp_termsOfService(MTPDhelp_termsOfService *_data) : mtpDataOwner(_data) {
|
||||||
|
}
|
||||||
|
inline MTPhelp_termsOfService MTP_help_termsOfService(const MTPstring &_text) {
|
||||||
|
return MTPhelp_termsOfService(new MTPDhelp_termsOfService(_text));
|
||||||
|
}
|
||||||
|
|
||||||
// Human-readable text serialization
|
// Human-readable text serialization
|
||||||
#if (defined _DEBUG || defined _WITH_DEBUG)
|
#if (defined _DEBUG || defined _WITH_DEBUG)
|
||||||
|
|
||||||
|
|
|
@ -305,6 +305,11 @@ peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool event
|
||||||
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
|
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
|
||||||
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
|
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
|
||||||
|
|
||||||
|
inputReportReasonSpam#58dbcab8 = ReportReason;
|
||||||
|
inputReportReasonViolence#1e22c78d = ReportReason;
|
||||||
|
inputReportReasonPornography#2e59d922 = ReportReason;
|
||||||
|
inputReportReasonOther#e1746d0a text:string = ReportReason;
|
||||||
|
|
||||||
userFull#5a89ac5b user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool bot_info:BotInfo = UserFull;
|
userFull#5a89ac5b user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool bot_info:BotInfo = UserFull;
|
||||||
|
|
||||||
contact#f911c994 user_id:int mutual:Bool = Contact;
|
contact#f911c994 user_id:int mutual:Bool = Contact;
|
||||||
|
@ -389,6 +394,9 @@ updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector<int> pts:int
|
||||||
updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update;
|
updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update;
|
||||||
updateChatAdmins#6e947941 chat_id:int enabled:Bool version:int = Update;
|
updateChatAdmins#6e947941 chat_id:int enabled:Bool version:int = Update;
|
||||||
updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update;
|
updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update;
|
||||||
|
updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
|
||||||
|
updateStickerSetsOrder#f0dfb451 order:Vector<long> = Update;
|
||||||
|
updateStickerSets#43ae3dec = Update;
|
||||||
|
|
||||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||||
|
|
||||||
|
@ -516,7 +524,7 @@ messages.stickers#8a8ecd32 hash:string stickers:Vector<Document> = messages.Stic
|
||||||
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
||||||
|
|
||||||
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
||||||
messages.allStickers#d51dafdb hash:string sets:Vector<StickerSet> = messages.AllStickers;
|
messages.allStickers#edfd405f hash:int sets:Vector<StickerSet> = messages.AllStickers;
|
||||||
|
|
||||||
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
|
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
|
||||||
|
|
||||||
|
@ -625,6 +633,8 @@ channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParti
|
||||||
|
|
||||||
channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
|
channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
|
||||||
|
|
||||||
|
help.termsOfService#f1ee3e90 text:string = help.TermsOfService;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||||
|
@ -658,6 +668,7 @@ account.resetNotifySettings#db7e1747 = Bool;
|
||||||
account.updateProfile#f0888d68 first_name:string last_name:string = User;
|
account.updateProfile#f0888d68 first_name:string last_name:string = User;
|
||||||
account.updateStatus#6628562c offline:Bool = Bool;
|
account.updateStatus#6628562c offline:Bool = Bool;
|
||||||
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
|
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
|
||||||
|
account.reportPeer#ae189d5f peer:InputPeer reason:ReportReason = Bool;
|
||||||
account.checkUsername#2714d86c username:string = Bool;
|
account.checkUsername#2714d86c username:string = Bool;
|
||||||
account.updateUsername#3e0bdd7c username:string = User;
|
account.updateUsername#3e0bdd7c username:string = User;
|
||||||
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
|
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
|
||||||
|
@ -725,7 +736,7 @@ messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long da
|
||||||
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
||||||
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
||||||
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
|
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
|
||||||
messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
|
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
||||||
messages.getWebPagePreview#25223e24 message:string = MessageMedia;
|
messages.getWebPagePreview#25223e24 message:string = MessageMedia;
|
||||||
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||||
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
||||||
|
@ -739,6 +750,7 @@ messages.toggleChatAdmins#ec8bd9e1 chat_id:int enabled:Bool = Updates;
|
||||||
messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
|
messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
|
||||||
messages.migrateChat#15a3b8e3 chat_id:int = Updates;
|
messages.migrateChat#15a3b8e3 chat_id:int = Updates;
|
||||||
messages.searchGlobal#9e3cacb0 q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
messages.searchGlobal#9e3cacb0 q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||||
|
messages.reorderStickerSets#9fcfbc30 order:Vector<long> = Bool;
|
||||||
|
|
||||||
updates.getState#edd4882a = updates.State;
|
updates.getState#edd4882a = updates.State;
|
||||||
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
|
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
|
||||||
|
@ -760,6 +772,7 @@ help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
|
||||||
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
|
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
|
||||||
help.getSupport#9cdf08cd = help.Support;
|
help.getSupport#9cdf08cd = help.Support;
|
||||||
help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog;
|
help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog;
|
||||||
|
help.getTermsOfService#37d78f83 lang_code:string = help.TermsOfService;
|
||||||
|
|
||||||
channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs;
|
channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs;
|
||||||
channels.getImportantHistory#ddb929cb channel:InputChannel offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
channels.getImportantHistory#ddb929cb channel:InputChannel offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
|
|
|
@ -1878,7 +1878,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
||||||
_menu->addAction(lang(cPlatform() == dbipMac ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
||||||
|
|
|
@ -78,7 +78,6 @@ void PasscodeWidget::onSubmit() {
|
||||||
} else {
|
} else {
|
||||||
if (Local::readMap(_passcode.text().toUtf8()) != Local::ReadMapPassNeeded) {
|
if (Local::readMap(_passcode.text().toUtf8()) != Local::ReadMapPassNeeded) {
|
||||||
cSetPasscodeBadTries(0);
|
cSetPasscodeBadTries(0);
|
||||||
App::app()->checkMapVersion();
|
|
||||||
|
|
||||||
MTP::start();
|
MTP::start();
|
||||||
if (MTP::authedId()) {
|
if (MTP::authedId()) {
|
||||||
|
@ -86,6 +85,8 @@ void PasscodeWidget::onSubmit() {
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->setupIntro(true);
|
App::wnd()->setupIntro(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App::app()->checkMapVersion();
|
||||||
} else {
|
} else {
|
||||||
cSetPasscodeBadTries(cPasscodeBadTries() + 1);
|
cSetPasscodeBadTries(cPasscodeBadTries() + 1);
|
||||||
cSetPasscodeLastTry(getms(true));
|
cSetPasscodeLastTry(getms(true));
|
||||||
|
|
|
@ -323,7 +323,7 @@ void PlayerWidget::preloadNext() {
|
||||||
}
|
}
|
||||||
if (next) {
|
if (next) {
|
||||||
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
|
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
|
||||||
if (document->document()->already(true).isEmpty() && document->document()->data.isEmpty()) {
|
if (document->document()->location(true).isEmpty() && document->document()->data.isEmpty()) {
|
||||||
if (!document->document()->loader) {
|
if (!document->document()->loader) {
|
||||||
DocumentOpenLink::doOpen(document->document());
|
DocumentOpenLink::doOpen(document->document());
|
||||||
document->document()->openOnSave = 0;
|
document->document()->openOnSave = 0;
|
||||||
|
|
|
@ -1167,7 +1167,7 @@ namespace {
|
||||||
void psRegisterCustomScheme() {
|
void psRegisterCustomScheme() {
|
||||||
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||||
QString home(_psHomeDir());
|
QString home(_psHomeDir());
|
||||||
if (home.isEmpty()) return;
|
if (home.isEmpty() || cBetaVersion()) return; // don't update desktop file for beta version
|
||||||
|
|
||||||
DEBUG_LOG(("App Info: placing .desktop file"));
|
DEBUG_LOG(("App Info: placing .desktop file"));
|
||||||
if (QDir(home + qsl(".local/")).exists()) {
|
if (QDir(home + qsl(".local/")).exists()) {
|
||||||
|
|
|
@ -175,5 +175,34 @@ void psUpdateOverlayed(QWidget *widget);
|
||||||
inline QString psConvertFileUrl(const QString &url) {
|
inline QString psConvertFileUrl(const QString &url) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
inline QByteArray psPathBookmark(const QString &path) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
inline void psDownloadPathEnableAccess() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class PsFileBookmark {
|
||||||
|
public:
|
||||||
|
PsFileBookmark(const QByteArray &bookmark) {
|
||||||
|
}
|
||||||
|
bool check() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool enable() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void disable() const {
|
||||||
|
}
|
||||||
|
const QString &name(const QString &original) const {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
QByteArray bookmark() const {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
bool linuxMoveFile(const char *from, const char *to);
|
bool linuxMoveFile(const char *from, const char *to);
|
||||||
|
|
|
@ -684,6 +684,18 @@ QString psConvertFileUrl(const QString &url) {
|
||||||
return objc_convertFileUrl(url);
|
return objc_convertFileUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void psDownloadPathEnableAccess() {
|
||||||
|
objc_downloadPathEnableAccess(cDownloadPathBookmark());
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray psDownloadPathBookmark(const QString &path) {
|
||||||
|
return objc_downloadPathBookmark(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray psPathBookmark(const QString &path) {
|
||||||
|
return objc_pathBookmark(path);
|
||||||
|
}
|
||||||
|
|
||||||
QString strNotificationAboutThemeChange() {
|
QString strNotificationAboutThemeChange() {
|
||||||
const uint32 letters[] = { 0xE9005541, 0x5600DC70, 0x88001570, 0xF500D86C, 0x8100E165, 0xEE005949, 0x2900526E, 0xAE00FB74, 0x96000865, 0x7000CD72, 0x3B001566, 0x5F007361, 0xAE00B663, 0x74009A65, 0x29003054, 0xC6002668, 0x98003865, 0xFA00336D, 0xA3007A65, 0x93001443, 0xBB007868, 0xE100E561, 0x3500366E, 0xC0007A67, 0x200CA65, 0xBE00DF64, 0xE300BB4E, 0x2900D26F, 0xD500D374, 0xE900E269, 0x86008F66, 0xC4006669, 0x1C00A863, 0xE600A761, 0x8E00EE74, 0xB300B169, 0xCF00B36F, 0xE600D36E };
|
const uint32 letters[] = { 0xE9005541, 0x5600DC70, 0x88001570, 0xF500D86C, 0x8100E165, 0xEE005949, 0x2900526E, 0xAE00FB74, 0x96000865, 0x7000CD72, 0x3B001566, 0x5F007361, 0xAE00B663, 0x74009A65, 0x29003054, 0xC6002668, 0x98003865, 0xFA00336D, 0xA3007A65, 0x93001443, 0xBB007868, 0xE100E561, 0x3500366E, 0xC0007A67, 0x200CA65, 0xBE00DF64, 0xE300BB4E, 0x2900D26F, 0xD500D374, 0xE900E269, 0x86008F66, 0xC4006669, 0x1C00A863, 0xE600A761, 0x8E00EE74, 0xB300B169, 0xCF00B36F, 0xE600D36E };
|
||||||
return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0]));
|
return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0]));
|
||||||
|
|
|
@ -198,6 +198,35 @@ void psNewVersion();
|
||||||
void psUpdateOverlayed(QWidget *widget);
|
void psUpdateOverlayed(QWidget *widget);
|
||||||
QString psConvertFileUrl(const QString &url);
|
QString psConvertFileUrl(const QString &url);
|
||||||
|
|
||||||
|
void psDownloadPathEnableAccess();
|
||||||
|
QByteArray psDownloadPathBookmark(const QString &path);
|
||||||
|
QByteArray psPathBookmark(const QString &path);
|
||||||
|
|
||||||
|
class PsFileBookmark {
|
||||||
|
public:
|
||||||
|
PsFileBookmark(const QByteArray &bookmark) : _inner(bookmark) {
|
||||||
|
}
|
||||||
|
bool check() const {
|
||||||
|
return _inner.valid();
|
||||||
|
}
|
||||||
|
bool enable() const {
|
||||||
|
return _inner.enable();
|
||||||
|
}
|
||||||
|
void disable() const {
|
||||||
|
return _inner.disable();
|
||||||
|
}
|
||||||
|
const QString &name(const QString &original) const {
|
||||||
|
return _inner.name(original);
|
||||||
|
}
|
||||||
|
QByteArray bookmark() const {
|
||||||
|
return _inner.bookmark();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
objc_FileBookmark _inner;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
QString strNotificationAboutThemeChange();
|
QString strNotificationAboutThemeChange();
|
||||||
QString strStyleOfInterface();
|
QString strStyleOfInterface();
|
||||||
QString strNeedToReload();
|
QString strNeedToReload();
|
||||||
|
|
|
@ -82,3 +82,20 @@ QString objc_downloadPath();
|
||||||
QString objc_currentCountry();
|
QString objc_currentCountry();
|
||||||
QString objc_currentLang();
|
QString objc_currentLang();
|
||||||
QString objc_convertFileUrl(const QString &url);
|
QString objc_convertFileUrl(const QString &url);
|
||||||
|
QByteArray objc_downloadPathBookmark(const QString &path);
|
||||||
|
QByteArray objc_pathBookmark(const QString &path);
|
||||||
|
void objc_downloadPathEnableAccess(const QByteArray &bookmark);
|
||||||
|
|
||||||
|
class objc_FileBookmark {
|
||||||
|
public:
|
||||||
|
objc_FileBookmark(const QByteArray &bookmark);
|
||||||
|
bool valid() const;
|
||||||
|
bool enable() const;
|
||||||
|
void disable() const;
|
||||||
|
|
||||||
|
const QString &name(const QString &original) const;
|
||||||
|
QByteArray bookmark() const;
|
||||||
|
|
||||||
|
~objc_FileBookmark();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -931,8 +931,16 @@ void objc_start() {
|
||||||
name: NSWorkspaceDidWakeNotification object: NULL];
|
name: NSWorkspaceDidWakeNotification object: NULL];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
NSURL *_downloadPathUrl = nil;
|
||||||
|
}
|
||||||
|
|
||||||
void objc_finish() {
|
void objc_finish() {
|
||||||
[_sharedDelegate release];
|
[_sharedDelegate release];
|
||||||
|
if (_downloadPathUrl) {
|
||||||
|
[_downloadPathUrl stopAccessingSecurityScopedResource];
|
||||||
|
_downloadPathUrl = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void objc_registerCustomScheme() {
|
void objc_registerCustomScheme() {
|
||||||
|
@ -1054,3 +1062,38 @@ QString objc_convertFileUrl(const QString &url) {
|
||||||
return objcString(nsurl);
|
return objcString(nsurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray objc_downloadPathBookmark(const QString &path) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray objc_pathBookmark(const QString &path) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void objc_downloadPathEnableAccess(const QByteArray &bookmark) {
|
||||||
|
}
|
||||||
|
|
||||||
|
objc_FileBookmark::objc_FileBookmark(const QByteArray &bookmark) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool objc_FileBookmark::valid() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool objc_FileBookmark::enable() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void objc_FileBookmark::disable() const {
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &objc_FileBookmark::name(const QString &original) const {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray objc_FileBookmark::bookmark() const {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
objc_FileBookmark::~objc_FileBookmark() {
|
||||||
|
}
|
||||||
|
|
|
@ -72,7 +72,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#define WM_NCPOINTERUP 0x0243
|
#define WM_NCPOINTERUP 0x0243
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const WCHAR AppUserModelId[] = L"Telegram.TelegramDesktop";
|
const WCHAR AppUserModelIdRelease[] = L"Telegram.TelegramDesktop";
|
||||||
|
const WCHAR AppUserModelIdBeta[] = L"Telegram.TelegramDesktop.Beta";
|
||||||
|
|
||||||
|
const WCHAR *AppUserModelId() {
|
||||||
|
return cBetaVersion() ? AppUserModelIdBeta : AppUserModelIdRelease;
|
||||||
|
}
|
||||||
|
|
||||||
static const PROPERTYKEY pkey_AppUserModel_ID = { { 0x9F4C2855, 0x9F79, 0x4B39, { 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 5 };
|
static const PROPERTYKEY pkey_AppUserModel_ID = { { 0x9F4C2855, 0x9F79, 0x4B39, { 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 5 };
|
||||||
static const PROPERTYKEY pkey_AppUserModel_StartPinOption = { { 0x9F4C2855, 0x9F79, 0x4B39, { 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 12 };
|
static const PROPERTYKEY pkey_AppUserModel_StartPinOption = { { 0x9F4C2855, 0x9F79, 0x4B39, { 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 12 };
|
||||||
|
@ -2301,7 +2306,7 @@ void _manageAppLnk(bool create, bool silent, int path_csidl, const wchar_t *args
|
||||||
hr = shellLink.As(&propertyStore);
|
hr = shellLink.As(&propertyStore);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
PROPVARIANT appIdPropVar;
|
PROPVARIANT appIdPropVar;
|
||||||
hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar);
|
hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
||||||
PropVariantClear(&appIdPropVar);
|
PropVariantClear(&appIdPropVar);
|
||||||
|
@ -2390,11 +2395,19 @@ HANDLE _generateDumpFileAtPath(const WCHAR *path) {
|
||||||
|
|
||||||
GetLocalTime(&stLocalTime);
|
GetLocalTime(&stLocalTime);
|
||||||
|
|
||||||
|
if (cBetaVersion()) {
|
||||||
|
wsprintf(szFileName, L"%s%s-%ld-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
|
||||||
|
szPath, szExeName, cBetaVersion(),
|
||||||
|
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
|
||||||
|
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
|
||||||
|
GetCurrentProcessId(), GetCurrentThreadId());
|
||||||
|
} else {
|
||||||
wsprintf(szFileName, L"%s%s-%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
|
wsprintf(szFileName, L"%s%s-%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
|
||||||
szPath, szExeName, AppVersionStr,
|
szPath, szExeName, AppVersionStr,
|
||||||
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
|
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
|
||||||
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
|
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
|
||||||
GetCurrentProcessId(), GetCurrentThreadId());
|
GetCurrentProcessId(), GetCurrentThreadId());
|
||||||
|
}
|
||||||
return CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
|
return CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2913,7 +2926,7 @@ void CheckPinnedAppUserModelId() {
|
||||||
WCHAR already[MAX_PATH];
|
WCHAR already[MAX_PATH];
|
||||||
hr = propVariantToString(appIdPropVar, already, MAX_PATH);
|
hr = propVariantToString(appIdPropVar, already, MAX_PATH);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
if (std::wstring(AppUserModelId) == already) {
|
if (std::wstring(AppUserModelId()) == already) {
|
||||||
LOG(("Already!"));
|
LOG(("Already!"));
|
||||||
PropVariantClear(&appIdPropVar);
|
PropVariantClear(&appIdPropVar);
|
||||||
return;
|
return;
|
||||||
|
@ -2925,7 +2938,7 @@ void CheckPinnedAppUserModelId() {
|
||||||
}
|
}
|
||||||
PropVariantClear(&appIdPropVar);
|
PropVariantClear(&appIdPropVar);
|
||||||
|
|
||||||
hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar);
|
hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar);
|
||||||
if (!SUCCEEDED(hr)) return;
|
if (!SUCCEEDED(hr)) return;
|
||||||
|
|
||||||
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
||||||
|
@ -3020,7 +3033,7 @@ bool ValidateAppUserModelIdShortcutAt(const QString &path) {
|
||||||
WCHAR already[MAX_PATH];
|
WCHAR already[MAX_PATH];
|
||||||
hr = propVariantToString(appIdPropVar, already, MAX_PATH);
|
hr = propVariantToString(appIdPropVar, already, MAX_PATH);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
if (std::wstring(AppUserModelId) == already) {
|
if (std::wstring(AppUserModelId()) == already) {
|
||||||
PropVariantClear(&appIdPropVar);
|
PropVariantClear(&appIdPropVar);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3031,7 +3044,7 @@ bool ValidateAppUserModelIdShortcutAt(const QString &path) {
|
||||||
}
|
}
|
||||||
PropVariantClear(&appIdPropVar);
|
PropVariantClear(&appIdPropVar);
|
||||||
|
|
||||||
hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar);
|
hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar);
|
||||||
if (!SUCCEEDED(hr)) return false;
|
if (!SUCCEEDED(hr)) return false;
|
||||||
|
|
||||||
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
||||||
|
@ -3054,11 +3067,16 @@ bool ValidateAppUserModelIdShortcut() {
|
||||||
QString path = systemShortcutPath();
|
QString path = systemShortcutPath();
|
||||||
if (path.isEmpty()) return false;
|
if (path.isEmpty()) return false;
|
||||||
|
|
||||||
|
if (cBetaVersion()) {
|
||||||
|
path += qsl("TelegramBeta.lnk");
|
||||||
|
if (ValidateAppUserModelIdShortcutAt(path)) return true;
|
||||||
|
} else {
|
||||||
if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Desktop/Telegram.lnk"))) return true;
|
if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Desktop/Telegram.lnk"))) return true;
|
||||||
if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Win (Unofficial)/Telegram.lnk"))) return true;
|
if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Win (Unofficial)/Telegram.lnk"))) return true;
|
||||||
|
|
||||||
path += qsl("Telegram.lnk");
|
path += qsl("Telegram.lnk");
|
||||||
if (ValidateAppUserModelIdShortcutAt(path)) return true;
|
if (ValidateAppUserModelIdShortcutAt(path)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
ComPtr<IShellLink> shellLink;
|
ComPtr<IShellLink> shellLink;
|
||||||
HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));
|
HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));
|
||||||
|
@ -3078,7 +3096,7 @@ bool ValidateAppUserModelIdShortcut() {
|
||||||
if (!SUCCEEDED(hr)) return false;
|
if (!SUCCEEDED(hr)) return false;
|
||||||
|
|
||||||
PROPVARIANT appIdPropVar;
|
PROPVARIANT appIdPropVar;
|
||||||
hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar);
|
hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar);
|
||||||
if (!SUCCEEDED(hr)) return false;
|
if (!SUCCEEDED(hr)) return false;
|
||||||
|
|
||||||
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar);
|
||||||
|
@ -3108,13 +3126,13 @@ bool ValidateAppUserModelIdShortcut() {
|
||||||
|
|
||||||
bool InitToastManager() {
|
bool InitToastManager() {
|
||||||
if (!useToast || !ValidateAppUserModelIdShortcut()) return false;
|
if (!useToast || !ValidateAppUserModelIdShortcut()) return false;
|
||||||
if (!SUCCEEDED(setCurrentProcessExplicitAppUserModelID(AppUserModelId))) {
|
if (!SUCCEEDED(setCurrentProcessExplicitAppUserModelID(AppUserModelId()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), &toastNotificationManager))) {
|
if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), &toastNotificationManager))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!SUCCEEDED(toastNotificationManager->CreateToastNotifierWithId(StringReferenceWrapper(AppUserModelId).Get(), &toastNotifier))) {
|
if (!SUCCEEDED(toastNotificationManager->CreateToastNotifierWithId(StringReferenceWrapper(AppUserModelId(), wcslen(AppUserModelId())).Get(), &toastNotifier))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &toastNotificationFactory))) {
|
if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &toastNotificationFactory))) {
|
||||||
|
|
|
@ -177,3 +177,32 @@ void psUpdateOverlayed(TWidget *widget);
|
||||||
inline QString psConvertFileUrl(const QString &url) {
|
inline QString psConvertFileUrl(const QString &url) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
inline QByteArray psPathBookmark(const QString &path) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
inline void psDownloadPathEnableAccess() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class PsFileBookmark {
|
||||||
|
public:
|
||||||
|
PsFileBookmark(const QByteArray &bookmark) {
|
||||||
|
}
|
||||||
|
bool check() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool enable() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void disable() const {
|
||||||
|
}
|
||||||
|
const QString &name(const QString &original) const {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
QByteArray bookmark() const {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -29,6 +29,10 @@ Qt::LayoutDirection gLangDir = gRtl ? Qt::RightToLeft : Qt::LeftToRight;
|
||||||
mtpDcOptions gDcOptions;
|
mtpDcOptions gDcOptions;
|
||||||
|
|
||||||
bool gDevVersion = DevVersion;
|
bool gDevVersion = DevVersion;
|
||||||
|
uint64 gBetaVersion = BETA_VERSION;
|
||||||
|
uint64 gRealBetaVersion = BETA_VERSION;
|
||||||
|
QByteArray gBetaPrivateKey;
|
||||||
|
|
||||||
bool gTestMode = false;
|
bool gTestMode = false;
|
||||||
bool gDebug = false;
|
bool gDebug = false;
|
||||||
bool gManyInstance = false;
|
bool gManyInstance = false;
|
||||||
|
@ -74,6 +78,7 @@ DBIDefaultAttach gDefaultAttach = dbidaDocument;
|
||||||
bool gReplaceEmojis = true;
|
bool gReplaceEmojis = true;
|
||||||
bool gAskDownloadPath = false;
|
bool gAskDownloadPath = false;
|
||||||
QString gDownloadPath;
|
QString gDownloadPath;
|
||||||
|
QByteArray gDownloadPathBookmark;
|
||||||
|
|
||||||
bool gNeedConfigResave = false;
|
bool gNeedConfigResave = false;
|
||||||
|
|
||||||
|
@ -99,12 +104,11 @@ bool gHasPasscode = false;
|
||||||
bool gHasAudioPlayer = true;
|
bool gHasAudioPlayer = true;
|
||||||
bool gHasAudioCapture = true;
|
bool gHasAudioCapture = true;
|
||||||
|
|
||||||
DBIEmojiTab gEmojiTab = dbietRecent;
|
|
||||||
RecentEmojiPack gRecentEmojis;
|
RecentEmojiPack gRecentEmojis;
|
||||||
RecentEmojisPreload gRecentEmojisPreload;
|
RecentEmojisPreload gRecentEmojisPreload;
|
||||||
EmojiColorVariants gEmojiVariants;
|
EmojiColorVariants gEmojiVariants;
|
||||||
|
|
||||||
QByteArray gStickersHash;
|
int32 gStickersHash = 0;
|
||||||
|
|
||||||
RecentStickerPreload gRecentStickersPreload;
|
RecentStickerPreload gRecentStickersPreload;
|
||||||
RecentStickerPack gRecentStickers;
|
RecentStickerPack gRecentStickers;
|
||||||
|
@ -143,6 +147,7 @@ QUrl gUpdateURL = QUrl(qsl("http://tdesktop.com/linux/tupdates/current"));
|
||||||
#else
|
#else
|
||||||
#error Unknown platform
|
#error Unknown platform
|
||||||
#endif
|
#endif
|
||||||
|
bool gIsElCapitan = false;
|
||||||
|
|
||||||
bool gContactsReceived = false;
|
bool gContactsReceived = false;
|
||||||
bool gDialogsReceived = false;
|
bool gDialogsReceived = false;
|
||||||
|
@ -168,8 +173,10 @@ ReportSpamStatuses gReportSpamStatuses;
|
||||||
|
|
||||||
void settingsParseArgs(int argc, char *argv[]) {
|
void settingsParseArgs(int argc, char *argv[]) {
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
gIsElCapitan = (QSysInfo::macVersion() >= QSysInfo::MV_10_11);
|
||||||
if (QSysInfo::macVersion() < QSysInfo::MV_10_8) {
|
if (QSysInfo::macVersion() < QSysInfo::MV_10_8) {
|
||||||
gUpdateURL = QUrl(qsl("http://tdesktop.com/mac32/tupdates/current"));
|
gUpdateURL = QUrl(qsl("http://tdesktop.com/mac32/tupdates/current"));
|
||||||
|
gPlatform = dbipMacOld;
|
||||||
} else {
|
} else {
|
||||||
gCustomNotifies = false;
|
gCustomNotifies = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,9 @@ typedef QMap<int, mtpDcOption> mtpDcOptions;
|
||||||
DeclareSetting(mtpDcOptions, DcOptions);
|
DeclareSetting(mtpDcOptions, DcOptions);
|
||||||
|
|
||||||
DeclareSetting(bool, DevVersion);
|
DeclareSetting(bool, DevVersion);
|
||||||
|
DeclareSetting(uint64, BetaVersion);
|
||||||
|
DeclareSetting(uint64, RealBetaVersion);
|
||||||
|
DeclareSetting(QByteArray, BetaPrivateKey);
|
||||||
|
|
||||||
DeclareSetting(bool, TestMode);
|
DeclareSetting(bool, TestMode);
|
||||||
DeclareSetting(QString, LoggedPhoneNumber);
|
DeclareSetting(QString, LoggedPhoneNumber);
|
||||||
|
@ -80,8 +83,7 @@ DeclareReadSetting(bool, FromAutoStart);
|
||||||
DeclareSetting(QString, WorkingDir);
|
DeclareSetting(QString, WorkingDir);
|
||||||
inline void cForceWorkingDir(const QString &newDir) {
|
inline void cForceWorkingDir(const QString &newDir) {
|
||||||
cSetWorkingDir(newDir);
|
cSetWorkingDir(newDir);
|
||||||
QDir dir;
|
if (!gWorkingDir.isEmpty()) QDir().mkpath(gWorkingDir);
|
||||||
if (!gWorkingDir.isEmpty()) dir.mkpath(gWorkingDir);
|
|
||||||
}
|
}
|
||||||
DeclareReadSetting(QString, ExeName);
|
DeclareReadSetting(QString, ExeName);
|
||||||
DeclareReadSetting(QString, ExeDir);
|
DeclareReadSetting(QString, ExeDir);
|
||||||
|
@ -134,6 +136,7 @@ DeclareSetting(bool, ReplaceEmojis);
|
||||||
DeclareReadSetting(bool, ManyInstance);
|
DeclareReadSetting(bool, ManyInstance);
|
||||||
DeclareSetting(bool, AskDownloadPath);
|
DeclareSetting(bool, AskDownloadPath);
|
||||||
DeclareSetting(QString, DownloadPath);
|
DeclareSetting(QString, DownloadPath);
|
||||||
|
DeclareSetting(QByteArray, DownloadPathBookmark);
|
||||||
DeclareSetting(QByteArray, LocalSalt);
|
DeclareSetting(QByteArray, LocalSalt);
|
||||||
DeclareSetting(DBIScale, RealScale);
|
DeclareSetting(DBIScale, RealScale);
|
||||||
DeclareSetting(DBIScale, ScreenScale);
|
DeclareSetting(DBIScale, ScreenScale);
|
||||||
|
@ -168,8 +171,6 @@ T convertScale(T v) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclareSetting(DBIEmojiTab, EmojiTab);
|
|
||||||
|
|
||||||
struct EmojiData {
|
struct EmojiData {
|
||||||
EmojiData(uint16 x, uint16 y, uint32 code, uint32 code2, uint16 len, uint16 postfix, uint32 color) : x(x), y(y), code(code), code2(code2), len(len), postfix(postfix), color(color) {
|
EmojiData(uint16 x, uint16 y, uint32 code, uint32 code2, uint16 len, uint16 postfix, uint32 color) : x(x), y(y), code(code), code2(code2), len(len), postfix(postfix), color(color) {
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,7 @@ RecentEmojiPack &cGetRecentEmojis();
|
||||||
|
|
||||||
struct DocumentData;
|
struct DocumentData;
|
||||||
typedef QVector<DocumentData*> StickerPack;
|
typedef QVector<DocumentData*> StickerPack;
|
||||||
DeclareSetting(QByteArray, StickersHash);
|
DeclareSetting(int32, StickersHash);
|
||||||
|
|
||||||
typedef QList<QPair<DocumentData*, int16> > RecentStickerPackOld;
|
typedef QList<QPair<DocumentData*, int16> > RecentStickerPackOld;
|
||||||
typedef QVector<QPair<uint64, ushort> > RecentStickerPreload;
|
typedef QVector<QPair<uint64, ushort> > RecentStickerPreload;
|
||||||
|
@ -297,6 +298,7 @@ DeclareSetting(bool, CustomNotifies);
|
||||||
DeclareReadSetting(uint64, Instance);
|
DeclareReadSetting(uint64, Instance);
|
||||||
|
|
||||||
DeclareReadSetting(DBIPlatform, Platform);
|
DeclareReadSetting(DBIPlatform, Platform);
|
||||||
|
DeclareReadSetting(bool, IsElCapitan);
|
||||||
DeclareReadSetting(QUrl, UpdateURL);
|
DeclareReadSetting(QUrl, UpdateURL);
|
||||||
|
|
||||||
DeclareSetting(bool, ContactsReceived);
|
DeclareSetting(bool, ContactsReceived);
|
||||||
|
|
|
@ -38,6 +38,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include "boxes/passcodebox.h"
|
#include "boxes/passcodebox.h"
|
||||||
#include "boxes/autolockbox.h"
|
#include "boxes/autolockbox.h"
|
||||||
#include "boxes/sessionsbox.h"
|
#include "boxes/sessionsbox.h"
|
||||||
|
#include "boxes/stickersetbox.h"
|
||||||
#include "langloaderplain.h"
|
#include "langloaderplain.h"
|
||||||
#include "gui/filedialog.h"
|
#include "gui/filedialog.h"
|
||||||
|
|
||||||
|
@ -156,9 +157,10 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||||
// chat options
|
// chat options
|
||||||
_replaceEmojis(this, lang(lng_settings_replace_emojis), cReplaceEmojis()),
|
_replaceEmojis(this, lang(lng_settings_replace_emojis), cReplaceEmojis()),
|
||||||
_viewEmojis(this, lang(lng_settings_view_emojis)),
|
_viewEmojis(this, lang(lng_settings_view_emojis)),
|
||||||
|
_stickers(this, lang(lng_stickers_you_have)),
|
||||||
|
|
||||||
_enterSend(this, qsl("send_key"), 0, lang(lng_settings_send_enter), !cCtrlEnter()),
|
_enterSend(this, qsl("send_key"), 0, lang(lng_settings_send_enter), !cCtrlEnter()),
|
||||||
_ctrlEnterSend(this, qsl("send_key"), 1, lang((cPlatform() == dbipMac) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter), cCtrlEnter()),
|
_ctrlEnterSend(this, qsl("send_key"), 1, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter), cCtrlEnter()),
|
||||||
|
|
||||||
_dontAskDownloadPath(this, lang(lng_download_path_dont_ask), !cAskDownloadPath()),
|
_dontAskDownloadPath(this, lang(lng_download_path_dont_ask), !cAskDownloadPath()),
|
||||||
_downloadPathWidth(st::linkFont->width(lang(lng_download_path_label)) + st::linkFont->spacew),
|
_downloadPathWidth(st::linkFont->width(lang(lng_download_path_label)) + st::linkFont->spacew),
|
||||||
|
@ -201,11 +203,12 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||||
{
|
{
|
||||||
if (self()) {
|
if (self()) {
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
|
connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
|
||||||
|
|
||||||
_nameText.setText(st::setNameFont, _nameCache, _textNameOptions);
|
_nameText.setText(st::setNameFont, _nameCache, _textNameOptions);
|
||||||
PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0;
|
PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0;
|
||||||
if (selfPhoto && selfPhoto->date) _photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self()));
|
if (selfPhoto && selfPhoto->date) _photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self()));
|
||||||
MTP::send(MTPusers_GetFullUser(self()->inputUser), rpcDone(&SettingsInner::gotFullSelf), RPCFailHandlerPtr(), 0, 10);
|
App::api()->requestFullPeer(self());
|
||||||
onReloadPassword();
|
onReloadPassword();
|
||||||
|
|
||||||
connect(App::main(), SIGNAL(peerPhotoChanged(PeerData *)), this, SLOT(peerUpdated(PeerData *)));
|
connect(App::main(), SIGNAL(peerPhotoChanged(PeerData *)), this, SLOT(peerUpdated(PeerData *)));
|
||||||
|
@ -253,7 +256,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||||
connect(&_dpiAutoScale, SIGNAL(changed()), this, SLOT(onScaleAuto()));
|
connect(&_dpiAutoScale, SIGNAL(changed()), this, SLOT(onScaleAuto()));
|
||||||
connect(&_dpiSlider, SIGNAL(changed(int32)), this, SLOT(onScaleChange()));
|
connect(&_dpiSlider, SIGNAL(changed(int32)), this, SLOT(onScaleChange()));
|
||||||
|
|
||||||
_curVersionText = lng_settings_current_version(lt_version, QString::fromWCharArray(AppVersionStr) + (cDevVersion() ? " dev" : "")) + ' ';
|
_curVersionText = lng_settings_current_version(lt_version, QString::fromWCharArray(AppVersionStr) + (cDevVersion() ? " dev" : "") + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())) + ' ';
|
||||||
_curVersionWidth = st::linkFont->width(_curVersionText);
|
_curVersionWidth = st::linkFont->width(_curVersionText);
|
||||||
_newVersionText = lang(lng_settings_update_ready) + ' ';
|
_newVersionText = lang(lng_settings_update_ready) + ' ';
|
||||||
_newVersionWidth = st::linkFont->width(_newVersionText);
|
_newVersionWidth = st::linkFont->width(_newVersionText);
|
||||||
|
@ -269,6 +272,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||||
// chat options
|
// chat options
|
||||||
connect(&_replaceEmojis, SIGNAL(changed()), this, SLOT(onReplaceEmojis()));
|
connect(&_replaceEmojis, SIGNAL(changed()), this, SLOT(onReplaceEmojis()));
|
||||||
connect(&_viewEmojis, SIGNAL(clicked()), this, SLOT(onViewEmojis()));
|
connect(&_viewEmojis, SIGNAL(clicked()), this, SLOT(onViewEmojis()));
|
||||||
|
connect(&_stickers, SIGNAL(clicked()), this, SLOT(onStickers()));
|
||||||
|
|
||||||
connect(&_enterSend, SIGNAL(changed()), this, SLOT(onEnterSend()));
|
connect(&_enterSend, SIGNAL(changed()), this, SLOT(onEnterSend()));
|
||||||
connect(&_ctrlEnterSend, SIGNAL(changed()), this, SLOT(onCtrlEnterSend()));
|
connect(&_ctrlEnterSend, SIGNAL(changed()), this, SLOT(onCtrlEnterSend()));
|
||||||
|
@ -343,7 +347,7 @@ void SettingsInner::peerUpdated(PeerData *data) {
|
||||||
_photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self()));
|
_photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self()));
|
||||||
} else {
|
} else {
|
||||||
_photoLink = TextLinkPtr();
|
_photoLink = TextLinkPtr();
|
||||||
MTP::send(MTPusers_GetFullUser(self()->inputUser), rpcDone(&SettingsInner::gotFullSelf));
|
App::api()->requestFullPeer(self());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_photoLink = TextLinkPtr();
|
_photoLink = TextLinkPtr();
|
||||||
|
@ -515,7 +519,8 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_chat));
|
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_chat));
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
|
|
||||||
top += _replaceEmojis.height() + st::setSectionSkip;
|
top += _replaceEmojis.height() + st::setLittleSkip;
|
||||||
|
top += _stickers.height() + st::setSectionSkip;
|
||||||
top += _enterSend.height() + st::setLittleSkip;
|
top += _enterSend.height() + st::setLittleSkip;
|
||||||
top += _ctrlEnterSend.height() + st::setSectionSkip;
|
top += _ctrlEnterSend.height() + st::setSectionSkip;
|
||||||
|
|
||||||
|
@ -706,7 +711,8 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||||
if (self()) {
|
if (self()) {
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
_viewEmojis.move(_left + st::setWidth - _viewEmojis.width(), top + st::cbDefFlat.textTop);
|
_viewEmojis.move(_left + st::setWidth - _viewEmojis.width(), top + st::cbDefFlat.textTop);
|
||||||
_replaceEmojis.move(_left, top); top += _replaceEmojis.height() + st::setSectionSkip;
|
_replaceEmojis.move(_left, top); top += _replaceEmojis.height() + st::setLittleSkip;
|
||||||
|
_stickers.move(_left + st::cbDefFlat.textLeft, top); top += _stickers.height() + st::setSectionSkip;
|
||||||
_enterSend.move(_left, top); top += _enterSend.height() + st::setLittleSkip;
|
_enterSend.move(_left, top); top += _enterSend.height() + st::setLittleSkip;
|
||||||
_ctrlEnterSend.move(_left, top); top += _ctrlEnterSend.height() + st::setSectionSkip;
|
_ctrlEnterSend.move(_left, top); top += _ctrlEnterSend.height() + st::setSectionSkip;
|
||||||
_dontAskDownloadPath.move(_left, top); top += _dontAskDownloadPath.height();
|
_dontAskDownloadPath.move(_left, top); top += _dontAskDownloadPath.height();
|
||||||
|
@ -892,10 +898,9 @@ void SettingsInner::updateBackgroundRect() {
|
||||||
update(_left, _tileBackground.y() - st::setLittleSkip - st::setBackgroundSize, st::setBackgroundSize, st::setBackgroundSize);
|
update(_left, _tileBackground.y() - st::setLittleSkip - st::setBackgroundSize, st::setBackgroundSize, st::setBackgroundSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsInner::gotFullSelf(const MTPUserFull &selfFull) {
|
void SettingsInner::onFullPeerUpdated(PeerData *peer) {
|
||||||
if (!self()) return;
|
if (!self() || self() != peer) return;
|
||||||
App::feedPhoto(selfFull.c_userFull().vprofile_photo);
|
|
||||||
App::feedUsers(MTP_vector<MTPUser>(1, selfFull.c_userFull().vuser));
|
|
||||||
PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0;
|
PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0;
|
||||||
if (selfPhoto && selfPhoto->date) {
|
if (selfPhoto && selfPhoto->date) {
|
||||||
_photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self()));
|
_photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self()));
|
||||||
|
@ -1040,6 +1045,7 @@ void SettingsInner::showAll() {
|
||||||
} else {
|
} else {
|
||||||
_viewEmojis.hide();
|
_viewEmojis.hide();
|
||||||
}
|
}
|
||||||
|
_stickers.show();
|
||||||
_enterSend.show();
|
_enterSend.show();
|
||||||
_ctrlEnterSend.show();
|
_ctrlEnterSend.show();
|
||||||
_dontAskDownloadPath.show();
|
_dontAskDownloadPath.show();
|
||||||
|
@ -1058,6 +1064,7 @@ void SettingsInner::showAll() {
|
||||||
} else {
|
} else {
|
||||||
_replaceEmojis.hide();
|
_replaceEmojis.hide();
|
||||||
_viewEmojis.hide();
|
_viewEmojis.hide();
|
||||||
|
_stickers.hide();
|
||||||
_enterSend.hide();
|
_enterSend.hide();
|
||||||
_ctrlEnterSend.hide();
|
_ctrlEnterSend.hide();
|
||||||
_dontAskDownloadPath.hide();
|
_dontAskDownloadPath.hide();
|
||||||
|
@ -1521,7 +1528,11 @@ void SettingsInner::onReplaceEmojis() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsInner::onViewEmojis() {
|
void SettingsInner::onViewEmojis() {
|
||||||
App::wnd()->showLayer(new EmojiBox());
|
App::showLayer(new EmojiBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsInner::onStickers() {
|
||||||
|
App::showLayer(new StickersBox());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsInner::onEnterSend() {
|
void SettingsInner::onEnterSend() {
|
||||||
|
|
|
@ -77,8 +77,6 @@ public:
|
||||||
|
|
||||||
void updateOnlineDisplay();
|
void updateOnlineDisplay();
|
||||||
|
|
||||||
void gotFullSelf(const MTPUserFull &self);
|
|
||||||
|
|
||||||
void showAll();
|
void showAll();
|
||||||
|
|
||||||
void chooseCustomLang();
|
void chooseCustomLang();
|
||||||
|
@ -107,6 +105,8 @@ public slots:
|
||||||
#endif
|
#endif
|
||||||
void onRestartNow();
|
void onRestartNow();
|
||||||
|
|
||||||
|
void onFullPeerUpdated(PeerData *peer);
|
||||||
|
|
||||||
void onPasscode();
|
void onPasscode();
|
||||||
void onPasscodeOff();
|
void onPasscodeOff();
|
||||||
void onAutoLock();
|
void onAutoLock();
|
||||||
|
@ -138,6 +138,7 @@ public slots:
|
||||||
|
|
||||||
void onReplaceEmojis();
|
void onReplaceEmojis();
|
||||||
void onViewEmojis();
|
void onViewEmojis();
|
||||||
|
void onStickers();
|
||||||
|
|
||||||
void onEnterSend();
|
void onEnterSend();
|
||||||
void onCtrlEnterSend();
|
void onCtrlEnterSend();
|
||||||
|
@ -242,7 +243,7 @@ private:
|
||||||
|
|
||||||
// chat options
|
// chat options
|
||||||
FlatCheckbox _replaceEmojis;
|
FlatCheckbox _replaceEmojis;
|
||||||
LinkButton _viewEmojis;
|
LinkButton _viewEmojis, _stickers;
|
||||||
FlatRadiobutton _enterSend, _ctrlEnterSend;
|
FlatRadiobutton _enterSend, _ctrlEnterSend;
|
||||||
FlatCheckbox _dontAskDownloadPath;
|
FlatCheckbox _dontAskDownloadPath;
|
||||||
int32 _downloadPathWidth;
|
int32 _downloadPathWidth;
|
||||||
|
|
|
@ -710,7 +710,7 @@ void VideoCancelLink::onClick(Qt::MouseButton button) const {
|
||||||
|
|
||||||
VideoData::VideoData(const VideoId &id, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) :
|
VideoData::VideoData(const VideoId &id, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) :
|
||||||
id(id), access(access), date(date), duration(duration), w(w), h(h), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), fileType(0), openOnSave(0), loader(0) {
|
id(id), access(access), date(date), duration(duration), w(w), h(h), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), fileType(0), openOnSave(0), loader(0) {
|
||||||
location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
_location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoData::save(const QString &toFile) {
|
void VideoData::save(const QString &toFile) {
|
||||||
|
@ -722,9 +722,12 @@ void VideoData::save(const QString &toFile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VideoData::already(bool check) {
|
QString VideoData::already(bool check) {
|
||||||
if (!check) return location.name;
|
return location(check).name();
|
||||||
if (!location.check()) location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
}
|
||||||
return location.name;
|
|
||||||
|
const FileLocation &VideoData::location(bool check) {
|
||||||
|
if (check && !_location.check()) _location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
||||||
|
return _location;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||||
|
@ -804,12 +807,15 @@ void AudioCancelLink::onClick(Qt::MouseButton button) const {
|
||||||
bool StickerData::setInstalled() const {
|
bool StickerData::setInstalled() const {
|
||||||
switch (set.type()) {
|
switch (set.type()) {
|
||||||
case mtpc_inputStickerSetID: {
|
case mtpc_inputStickerSetID: {
|
||||||
return (cStickerSets().constFind(set.c_inputStickerSetID().vid.v) != cStickerSets().cend());
|
StickerSets::const_iterator it = cStickerSets().constFind(set.c_inputStickerSetID().vid.v);
|
||||||
|
return (it != cStickerSets().cend()) && !(it->flags & MTPDstickerSet::flag_disabled);
|
||||||
} break;
|
} break;
|
||||||
case mtpc_inputStickerSetShortName: {
|
case mtpc_inputStickerSetShortName: {
|
||||||
QString name = qs(set.c_inputStickerSetShortName().vshort_name).toLower();
|
QString name = qs(set.c_inputStickerSetShortName().vshort_name).toLower();
|
||||||
for (StickerSets::const_iterator i = cStickerSets().cbegin(), e = cStickerSets().cend(); i != e; ++i) {
|
for (StickerSets::const_iterator it = cStickerSets().cbegin(), e = cStickerSets().cend(); it != e; ++it) {
|
||||||
if (i->shortName.toLower() == name) return true;
|
if (it->shortName.toLower() == name) {
|
||||||
|
return !(it->flags & MTPDstickerSet::flag_disabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@ -818,7 +824,7 @@ bool StickerData::setInstalled() const {
|
||||||
|
|
||||||
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) :
|
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) :
|
||||||
id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0) {
|
id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0) {
|
||||||
location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
_location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioData::save(const QString &toFile) {
|
void AudioData::save(const QString &toFile) {
|
||||||
|
@ -830,17 +836,20 @@ void AudioData::save(const QString &toFile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AudioData::already(bool check) {
|
QString AudioData::already(bool check) {
|
||||||
if (!check) return location.name;
|
return location(check).name();
|
||||||
if (!location.check()) location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
}
|
||||||
return location.name;
|
|
||||||
|
const FileLocation &AudioData::location(bool check) {
|
||||||
|
if (check && !_location.check()) _location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
||||||
|
return _location;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentOpenLink::doOpen(DocumentData *data) {
|
void DocumentOpenLink::doOpen(DocumentData *data) {
|
||||||
if (!data->date) return;
|
if (!data->date) return;
|
||||||
|
|
||||||
bool play = data->song() && App::hoveredLinkItem() && audioPlayer();
|
bool play = data->song() && App::hoveredLinkItem() && audioPlayer();
|
||||||
QString already = data->already(true);
|
const FileLocation &location(data->location(true));
|
||||||
if (!already.isEmpty() || (!data->data.isEmpty() && play)) {
|
if (!location.isEmpty() || (!data->data.isEmpty() && play)) {
|
||||||
if (play) {
|
if (play) {
|
||||||
SongMsgId playing;
|
SongMsgId playing;
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
|
@ -852,21 +861,22 @@ void DocumentOpenLink::doOpen(DocumentData *data) {
|
||||||
audioPlayer()->play(song);
|
audioPlayer()->play(song);
|
||||||
if (App::main()) App::main()->documentPlayProgress(song);
|
if (App::main()) App::main()->documentPlayProgress(song);
|
||||||
}
|
}
|
||||||
} else if (data->size < MediaViewImageSizeLimit) {
|
} else if (data->size < MediaViewImageSizeLimit && location.accessEnable()) {
|
||||||
QImageReader reader(already);
|
QImageReader reader(location.name());
|
||||||
if (reader.canRead()) {
|
if (reader.canRead()) {
|
||||||
if (reader.supportsAnimation() && reader.imageCount() > 1 && App::hoveredLinkItem()) {
|
if (reader.supportsAnimation() && reader.imageCount() > 1 && App::hoveredLinkItem()) {
|
||||||
startGif(App::hoveredLinkItem(), already);
|
startGif(App::hoveredLinkItem(), location);
|
||||||
} else if (App::hoveredLinkItem() || App::contextItem()) {
|
} else if (App::hoveredLinkItem() || App::contextItem()) {
|
||||||
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem());
|
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem());
|
||||||
} else {
|
} else {
|
||||||
psOpenFile(already);
|
psOpenFile(location.name());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
psOpenFile(already);
|
psOpenFile(location.name());
|
||||||
}
|
}
|
||||||
|
location.accessDisable();
|
||||||
} else {
|
} else {
|
||||||
psOpenFile(already);
|
psOpenFile(location.name());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -954,7 +964,7 @@ void DocumentCancelLink::onClick(Qt::MouseButton button) const {
|
||||||
DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size) :
|
DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size) :
|
||||||
id(id), type(FileDocument), access(access), date(date), mime(mime), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0), _additional(0) {
|
id(id), type(FileDocument), access(access), date(date), mime(mime), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0), _additional(0) {
|
||||||
setattributes(attributes);
|
setattributes(attributes);
|
||||||
location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
_location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes) {
|
void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes) {
|
||||||
|
@ -1016,9 +1026,12 @@ void DocumentData::save(const QString &toFile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DocumentData::already(bool check) {
|
QString DocumentData::already(bool check) {
|
||||||
if (!check) return location.name;
|
return location(check).name();
|
||||||
if (!location.check()) location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
}
|
||||||
return location.name;
|
|
||||||
|
const FileLocation &DocumentData::location(bool check) {
|
||||||
|
if (check && !_location.check()) _location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||||
|
return _location;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill) :
|
WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill) :
|
||||||
|
|
|
@ -807,7 +807,7 @@ struct VideoData {
|
||||||
l->deleteLater();
|
l->deleteLater();
|
||||||
l->rpcInvalidate();
|
l->rpcInvalidate();
|
||||||
}
|
}
|
||||||
location = FileLocation();
|
_location = FileLocation();
|
||||||
if (!beforeDownload) {
|
if (!beforeDownload) {
|
||||||
openOnSave = 0;
|
openOnSave = 0;
|
||||||
openOnSaveMsgId = FullMsgId();
|
openOnSaveMsgId = FullMsgId();
|
||||||
|
@ -816,7 +816,7 @@ struct VideoData {
|
||||||
|
|
||||||
void finish() {
|
void finish() {
|
||||||
if (loader->done()) {
|
if (loader->done()) {
|
||||||
location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
_location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||||
}
|
}
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
loader->rpcInvalidate();
|
loader->rpcInvalidate();
|
||||||
|
@ -824,6 +824,7 @@ struct VideoData {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString already(bool check = false);
|
QString already(bool check = false);
|
||||||
|
const FileLocation &location(bool check = false);
|
||||||
|
|
||||||
VideoId id;
|
VideoId id;
|
||||||
uint64 access;
|
uint64 access;
|
||||||
|
@ -841,7 +842,10 @@ struct VideoData {
|
||||||
int32 openOnSave;
|
int32 openOnSave;
|
||||||
FullMsgId openOnSaveMsgId;
|
FullMsgId openOnSaveMsgId;
|
||||||
mtpFileLoader *loader;
|
mtpFileLoader *loader;
|
||||||
FileLocation location;
|
|
||||||
|
private:
|
||||||
|
FileLocation _location;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VideoLink : public ITextLink {
|
class VideoLink : public ITextLink {
|
||||||
|
@ -902,7 +906,7 @@ struct AudioData {
|
||||||
l->deleteLater();
|
l->deleteLater();
|
||||||
l->rpcInvalidate();
|
l->rpcInvalidate();
|
||||||
}
|
}
|
||||||
location = FileLocation();
|
_location = FileLocation();
|
||||||
if (!beforeDownload) {
|
if (!beforeDownload) {
|
||||||
openOnSave = 0;
|
openOnSave = 0;
|
||||||
openOnSaveMsgId = FullMsgId();
|
openOnSaveMsgId = FullMsgId();
|
||||||
|
@ -911,7 +915,7 @@ struct AudioData {
|
||||||
|
|
||||||
void finish() {
|
void finish() {
|
||||||
if (loader->done()) {
|
if (loader->done()) {
|
||||||
location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
_location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||||
data = loader->bytes();
|
data = loader->bytes();
|
||||||
}
|
}
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
|
@ -920,6 +924,12 @@ struct AudioData {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString already(bool check = false);
|
QString already(bool check = false);
|
||||||
|
const FileLocation &location(bool check = false);
|
||||||
|
void setLocation(const FileLocation &loc) {
|
||||||
|
if (loc.check()) {
|
||||||
|
_location = loc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AudioId id;
|
AudioId id;
|
||||||
uint64 access;
|
uint64 access;
|
||||||
|
@ -935,9 +945,12 @@ struct AudioData {
|
||||||
int32 openOnSave;
|
int32 openOnSave;
|
||||||
FullMsgId openOnSaveMsgId;
|
FullMsgId openOnSaveMsgId;
|
||||||
mtpFileLoader *loader;
|
mtpFileLoader *loader;
|
||||||
FileLocation location;
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
int32 md5[8];
|
int32 md5[8];
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileLocation _location;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AudioMsgId {
|
struct AudioMsgId {
|
||||||
|
@ -1068,7 +1081,7 @@ struct DocumentData {
|
||||||
l->deleteLater();
|
l->deleteLater();
|
||||||
l->rpcInvalidate();
|
l->rpcInvalidate();
|
||||||
}
|
}
|
||||||
location = FileLocation();
|
_location = FileLocation();
|
||||||
if (!beforeDownload) {
|
if (!beforeDownload) {
|
||||||
openOnSave = 0;
|
openOnSave = 0;
|
||||||
openOnSaveMsgId = FullMsgId();
|
openOnSaveMsgId = FullMsgId();
|
||||||
|
@ -1077,7 +1090,7 @@ struct DocumentData {
|
||||||
|
|
||||||
void finish() {
|
void finish() {
|
||||||
if (loader->done()) {
|
if (loader->done()) {
|
||||||
location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
_location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||||
data = loader->bytes();
|
data = loader->bytes();
|
||||||
if (sticker() && !loader->imagePixmap().isNull()) {
|
if (sticker() && !loader->imagePixmap().isNull()) {
|
||||||
sticker()->img = ImagePtr(data, loader->imageFormat(), loader->imagePixmap());
|
sticker()->img = ImagePtr(data, loader->imageFormat(), loader->imagePixmap());
|
||||||
|
@ -1092,6 +1105,12 @@ struct DocumentData {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString already(bool check = false);
|
QString already(bool check = false);
|
||||||
|
const FileLocation &location(bool check = false);
|
||||||
|
void setLocation(const FileLocation &loc) {
|
||||||
|
if (loc.check()) {
|
||||||
|
_location = loc;
|
||||||
|
}
|
||||||
|
}
|
||||||
StickerData *sticker() {
|
StickerData *sticker() {
|
||||||
return (type == StickerDocument) ? static_cast<StickerData*>(_additional) : 0;
|
return (type == StickerDocument) ? static_cast<StickerData*>(_additional) : 0;
|
||||||
}
|
}
|
||||||
|
@ -1115,12 +1134,15 @@ struct DocumentData {
|
||||||
int32 openOnSave;
|
int32 openOnSave;
|
||||||
FullMsgId openOnSaveMsgId;
|
FullMsgId openOnSaveMsgId;
|
||||||
mtpFileLoader *loader;
|
mtpFileLoader *loader;
|
||||||
FileLocation location;
|
|
||||||
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
DocumentAdditionalData *_additional;
|
DocumentAdditionalData *_additional;
|
||||||
|
|
||||||
int32 md5[8];
|
int32 md5[8];
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FileLocation _location;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SongMsgId {
|
struct SongMsgId {
|
||||||
|
|
|
@ -258,9 +258,9 @@ enum DataBlockId {
|
||||||
dbiCatsAndDogs = 0x12,
|
dbiCatsAndDogs = 0x12,
|
||||||
dbiReplaceEmojis = 0x13,
|
dbiReplaceEmojis = 0x13,
|
||||||
dbiAskDownloadPath = 0x14,
|
dbiAskDownloadPath = 0x14,
|
||||||
dbiDownloadPath = 0x15,
|
dbiDownloadPathOld = 0x15,
|
||||||
dbiScale = 0x16,
|
dbiScale = 0x16,
|
||||||
dbiEmojiTab = 0x17,
|
dbiEmojiTabOld = 0x17,
|
||||||
dbiRecentEmojisOld = 0x18,
|
dbiRecentEmojisOld = 0x18,
|
||||||
dbiLoggedPhoneNumber = 0x19,
|
dbiLoggedPhoneNumber = 0x19,
|
||||||
dbiMutedPeers = 0x1a,
|
dbiMutedPeers = 0x1a,
|
||||||
|
@ -282,6 +282,7 @@ enum DataBlockId {
|
||||||
dbiWindowsNotifications = 0x30,
|
dbiWindowsNotifications = 0x30,
|
||||||
dbiIncludeMuted = 0x31,
|
dbiIncludeMuted = 0x31,
|
||||||
dbiMaxMegaGroupCount = 0x32,
|
dbiMaxMegaGroupCount = 0x32,
|
||||||
|
dbiDownloadPath = 0x33,
|
||||||
|
|
||||||
dbiEncryptedWithSalt = 333,
|
dbiEncryptedWithSalt = 333,
|
||||||
dbiEncrypted = 444,
|
dbiEncrypted = 444,
|
||||||
|
@ -345,10 +346,10 @@ enum DBIEmojiTab {
|
||||||
dbietPeople = 0,
|
dbietPeople = 0,
|
||||||
dbietNature = 1,
|
dbietNature = 1,
|
||||||
dbietFood = 2,
|
dbietFood = 2,
|
||||||
dbietCelebration = 3,
|
dbietActivity = 3,
|
||||||
dbietActivity = 4,
|
dbietTravel = 4,
|
||||||
dbietTravel = 5,
|
dbietObjects = 5,
|
||||||
dbietObjects = 6,
|
dbietSymbols = 6,
|
||||||
dbietStickers = 666,
|
dbietStickers = 666,
|
||||||
};
|
};
|
||||||
static const int emojiTabCount = 8;
|
static const int emojiTabCount = 8;
|
||||||
|
@ -361,6 +362,7 @@ enum DBIPlatform {
|
||||||
dbipMac = 1,
|
dbipMac = 1,
|
||||||
dbipLinux64 = 2,
|
dbipLinux64 = 2,
|
||||||
dbipLinux32 = 3,
|
dbipLinux32 = 3,
|
||||||
|
dbipMacOld = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DBIPeerReportSpamStatus {
|
enum DBIPeerReportSpamStatus {
|
||||||
|
@ -434,3 +436,10 @@ inline int32 ceilclamp(int32 value, int32 step, int32 lowest, int32 highest) {
|
||||||
inline int32 ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) {
|
inline int32 ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) {
|
||||||
return qMax(qMin(qCeil(value / step), highest), lowest);
|
return qMax(qMin(qCeil(value / step), highest), lowest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ForwardWhatMessages {
|
||||||
|
ForwardSelectedMessages,
|
||||||
|
ForwardContextMessage,
|
||||||
|
ForwardPressedMessage,
|
||||||
|
ForwardPressedLinkMessage
|
||||||
|
};
|
||||||
|
|
|
@ -453,7 +453,7 @@ void Window::firstShow() {
|
||||||
QString notificationItem = lang(cDesktopNotify()
|
QString notificationItem = lang(cDesktopNotify()
|
||||||
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray);
|
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray);
|
||||||
|
|
||||||
if (cPlatform() == dbipWindows || cPlatform() == dbipMac) {
|
if (cPlatform() == dbipWindows || cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true);
|
trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true);
|
||||||
trayIconMenu->addAction(notificationItem, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true);
|
trayIconMenu->addAction(notificationItem, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true);
|
||||||
trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray()))->setEnabled(true);
|
trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray()))->setEnabled(true);
|
||||||
|
@ -987,6 +987,8 @@ bool Window::eventFilter(QObject *obj, QEvent *evt) {
|
||||||
psUserActionDone();
|
psUserActionDone();
|
||||||
main->checkIdleFinish();
|
main->checkIdleFinish();
|
||||||
}
|
}
|
||||||
|
} else if (t == QEvent::MouseButtonRelease) {
|
||||||
|
Ui::hideStickerPreview();
|
||||||
}
|
}
|
||||||
if (obj == App::app()) {
|
if (obj == App::app()) {
|
||||||
if (t == QEvent::ApplicationActivate) {
|
if (t == QEvent::ApplicationActivate) {
|
||||||
|
@ -1056,7 +1058,7 @@ void Window::updateTrayMenu(bool force) {
|
||||||
QString notificationItem = lang(cDesktopNotify()
|
QString notificationItem = lang(cDesktopNotify()
|
||||||
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray);
|
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray);
|
||||||
|
|
||||||
if (cPlatform() == dbipWindows || cPlatform() == dbipMac) {
|
if (cPlatform() == dbipWindows || cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
QAction *toggle = trayIconMenu->actions().at(0);
|
QAction *toggle = trayIconMenu->actions().at(0);
|
||||||
disconnect(toggle, SIGNAL(triggered(bool)), this, SLOT(minimizeToTray()));
|
disconnect(toggle, SIGNAL(triggered(bool)), this, SLOT(minimizeToTray()));
|
||||||
disconnect(toggle, SIGNAL(triggered(bool)), this, SLOT(showFromTray()));
|
disconnect(toggle, SIGNAL(triggered(bool)), this, SLOT(showFromTray()));
|
||||||
|
@ -1072,7 +1074,7 @@ void Window::updateTrayMenu(bool force) {
|
||||||
}
|
}
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
if (trayIcon) {
|
if (trayIcon) {
|
||||||
trayIcon->setContextMenu((active || cPlatform() != dbipMac) ? trayIconMenu : 0);
|
trayIcon->setContextMenu((active || cPlatform() == dbipLinux32 || cPlatform() == dbipLinux64) ? trayIconMenu : 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1180,7 +1182,7 @@ void Window::showFromTray(QSystemTrayIcon::ActivationReason reason) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::toggleTray(QSystemTrayIcon::ActivationReason reason) {
|
void Window::toggleTray(QSystemTrayIcon::ActivationReason reason) {
|
||||||
if (cPlatform() == dbipMac && isActive(false)) return;
|
if ((cPlatform() == dbipMac || cPlatform() == dbipMacOld) && isActive(false)) return;
|
||||||
if (reason == QSystemTrayIcon::Context) {
|
if (reason == QSystemTrayIcon::Context) {
|
||||||
updateTrayMenu(true);
|
updateTrayMenu(true);
|
||||||
QTimer::singleShot(1, this, SLOT(psShowTrayMenu()));
|
QTimer::singleShot(1, this, SLOT(psShowTrayMenu()));
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.9.13</string>
|
<string>0.9.15</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
|
|
|
@ -89,6 +89,7 @@ SOURCES += \
|
||||||
./SourceFiles/autoupdater.cpp \
|
./SourceFiles/autoupdater.cpp \
|
||||||
./SourceFiles/dialogswidget.cpp \
|
./SourceFiles/dialogswidget.cpp \
|
||||||
./SourceFiles/dropdown.cpp \
|
./SourceFiles/dropdown.cpp \
|
||||||
|
./SourceFiles/facades.cpp \
|
||||||
./SourceFiles/fileuploader.cpp \
|
./SourceFiles/fileuploader.cpp \
|
||||||
./SourceFiles/history.cpp \
|
./SourceFiles/history.cpp \
|
||||||
./SourceFiles/historywidget.cpp \
|
./SourceFiles/historywidget.cpp \
|
||||||
|
@ -112,6 +113,7 @@ SOURCES += \
|
||||||
./SourceFiles/types.cpp \
|
./SourceFiles/types.cpp \
|
||||||
./SourceFiles/window.cpp \
|
./SourceFiles/window.cpp \
|
||||||
./SourceFiles/mtproto/mtp.cpp \
|
./SourceFiles/mtproto/mtp.cpp \
|
||||||
|
./SourceFiles/mtproto/mtpAuthKey.cpp \
|
||||||
./SourceFiles/mtproto/mtpConnection.cpp \
|
./SourceFiles/mtproto/mtpConnection.cpp \
|
||||||
./SourceFiles/mtproto/mtpCoreTypes.cpp \
|
./SourceFiles/mtproto/mtpCoreTypes.cpp \
|
||||||
./SourceFiles/mtproto/mtpDC.cpp \
|
./SourceFiles/mtproto/mtpDC.cpp \
|
||||||
|
@ -175,6 +177,7 @@ HEADERS += \
|
||||||
./SourceFiles/countries.h \
|
./SourceFiles/countries.h \
|
||||||
./SourceFiles/dialogswidget.h \
|
./SourceFiles/dialogswidget.h \
|
||||||
./SourceFiles/dropdown.h \
|
./SourceFiles/dropdown.h \
|
||||||
|
./SourceFiles/facades.h \
|
||||||
./SourceFiles/fileuploader.h \
|
./SourceFiles/fileuploader.h \
|
||||||
./SourceFiles/history.h \
|
./SourceFiles/history.h \
|
||||||
./SourceFiles/historywidget.h \
|
./SourceFiles/historywidget.h \
|
||||||
|
|
|
@ -68,8 +68,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,9,13,0
|
FILEVERSION 0,9,15,0
|
||||||
PRODUCTVERSION 0,9,13,0
|
PRODUCTVERSION 0,9,15,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -85,10 +85,10 @@ BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "0.9.13.0"
|
VALUE "FileVersion", "0.9.15.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2013"
|
VALUE "LegalCopyright", "Copyright (C) 2013"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.9.13.0"
|
VALUE "ProductVersion", "0.9.15.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|