Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b9cdbd98a | ||
|
|
8bb376798e | ||
|
|
7d51682edd | ||
|
|
f37159911c | ||
|
|
4f7f569ddd | ||
|
|
b352d38acf | ||
|
|
5663841742 | ||
|
|
8e2943fe11 | ||
|
|
5595570dfe | ||
|
|
afa28e9754 | ||
|
|
5a38cb4581 | ||
|
|
cf119568a1 | ||
|
|
8b1195df8d | ||
|
|
7021156732 | ||
|
|
4f2ff9e343 | ||
|
|
3dc7c3e776 | ||
|
|
e509c14ed1 | ||
|
|
a65ef6fb00 | ||
|
|
4c1d12fa70 | ||
|
|
1268774517 | ||
|
|
61a2a44584 | ||
|
|
89d68cab3e | ||
|
|
f7d55005c4 | ||
|
|
387694f477 | ||
|
|
bc58c73fb4 | ||
|
|
a4223ec3e0 | ||
|
|
d57f6a973f | ||
|
|
24ffa08d6e | ||
|
|
4b2fccf762 | ||
|
|
da5887fbb5 | ||
|
|
9926357af5 | ||
|
|
ef9aaf659c | ||
|
|
dd797d5d46 | ||
|
|
9c91bc1677 | ||
|
|
4f3aaa3e7f | ||
|
|
51451181f8 | ||
|
|
405dfbebae | ||
|
|
8e82b8894d | ||
|
|
b84101b12e | ||
|
|
5182c58292 | ||
|
|
d81d6bbeaa | ||
|
|
ddac19788f | ||
|
|
990c085fc5 | ||
|
|
2940561ee2 | ||
|
|
890352ef97 | ||
|
|
88c44caf9d | ||
|
|
3f6664c82a | ||
|
|
793a2ec90c | ||
|
|
780d00bd8c |
@@ -1,20 +1,21 @@
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $2}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $3}'`
|
||||
AppVersionStrMajor=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $2}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $3}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $4}'`
|
||||
DevPostfix=''
|
||||
if [ "$DevChannel" != "0" ]; then
|
||||
DevPostfix='.dev'
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tlinuxupd$AppVersion" ]; then
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tlinuxupd$AppVersion" ]; then
|
||||
echo "tlinuxupd$AppVersion not found!";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.tar.xz" ]; then
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.tar.xz" ]; then
|
||||
echo "tsetup.$AppVersionStr$DevPostfix.tar.xz not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
scp ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tlinuxupd$AppVersion tmaster:tdesktop/www/tlinux/
|
||||
scp ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.tar.xz tmaster:tdesktop/www/tlinux/
|
||||
scp ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tlinuxupd$AppVersion tmaster:tdesktop/www/tlinux/
|
||||
scp ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.tar.xz tmaster:tdesktop/www/tlinux/
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $2}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $3}'`
|
||||
AppVersionStrMajor=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $2}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $3}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $4}'`
|
||||
DevPostfix=''
|
||||
if [ "$DevChannel" != "0" ]; then
|
||||
DevPostfix='.dev'
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tlinux32upd$AppVersion" ]; then
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tlinux32upd$AppVersion" ]; then
|
||||
echo "tlinux32upd$AppVersion not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tsetup32.$AppVersionStr$DevPostfix.tar.xz" ]; then
|
||||
if [ ! -f "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup32.$AppVersionStr$DevPostfix.tar.xz" ]; then
|
||||
echo "tsetup32.$AppVersionStr$DevPostfix.zip not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
scp ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tlinux32upd$AppVersion tmaster:tdesktop/www/tlinux32/
|
||||
scp ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/tsetup32.$AppVersionStr$DevPostfix.tar.xz tmaster:tdesktop/www/tlinux32/
|
||||
scp ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tlinux32upd$AppVersion tmaster:tdesktop/www/tlinux32/
|
||||
scp ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup32.$AppVersionStr$DevPostfix.tar.xz tmaster:tdesktop/www/tlinux32/
|
||||
|
||||
|
||||
@@ -1,38 +1,50 @@
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $2}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $3}'`
|
||||
AppVersionStrMajor=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $2}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $3}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $4}'`
|
||||
DevPostfix=''
|
||||
if [ "$DevChannel" != "0" ]; then
|
||||
DevPostfix='.dev'
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Mac/Release/deploy/$AppVersionStr$DevPostfix/tmacupd$AppVersion" ]; then
|
||||
echo "tmacupd$AppVersion not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmacupd$AppVersion" ]; then
|
||||
echo "tmacupd$AppVersion not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Mac/Release/deploy/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg" ]; then
|
||||
echo "tsetup.$AppVersionStr$DevPostfix.dmg not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg" ]; then
|
||||
echo "tsetup.$AppVersionStr$DevPostfix.dmg not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../../tother/tsetup/tupdate$AppVersion" ]; then
|
||||
echo "tupdate$AppVersion not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tupdate$AppVersion" ]; then
|
||||
echo "tupdate$AppVersion not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../../tother/tsetup/tportable.$AppVersionStr$DevPostfix.zip" ]; then
|
||||
echo "tportable.$AppVersionStr$DevPostfix.zip not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tportable.$AppVersionStr$DevPostfix.zip" ]; then
|
||||
echo "tportable.$AppVersionStr$DevPostfix.zip not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../../tother/tsetup/tsetup.$AppVersionStr$DevPostfix.exe" ]; then
|
||||
echo "tsetup.$AppVersionStr$DevPostfix.exe not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.exe" ]; then
|
||||
echo "tsetup.$AppVersionStr$DevPostfix.exe not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
scp ./../Mac/Release/deploy/$AppVersionStr$DevPostfix/tmacupd$AppVersion tmaster:tdesktop/www/tmac/
|
||||
scp ./../Mac/Release/deploy/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg tmaster:tdesktop/www/tmac/
|
||||
scp ./../../tother/tsetup/tupdate$AppVersion tmaster:tdesktop/www/tsetup/
|
||||
scp ./../../tother/tsetup/tportable.$AppVersionStr$DevPostfix.zip tmaster:tdesktop/www/tsetup/
|
||||
scp ./../../tother/tsetup/tsetup.$AppVersionStr$DevPostfix.exe tmaster:tdesktop/www/tsetup/
|
||||
if [ ! -d "./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor" ]; then
|
||||
mkdir "./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor"
|
||||
fi
|
||||
|
||||
scp ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmacupd$AppVersion tmaster:tdesktop/www/tmac/
|
||||
scp ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg tmaster:tdesktop/www/tmac/
|
||||
scp ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tupdate$AppVersion tmaster:tdesktop/www/tsetup/
|
||||
scp ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tportable.$AppVersionStr$DevPostfix.zip tmaster:tdesktop/www/tsetup/
|
||||
scp ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.exe tmaster:tdesktop/www/tsetup/
|
||||
|
||||
mv -v ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/
|
||||
|
||||
cp -v ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmacupd$AppVersion ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -rv ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram.app.dSYM ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
|
||||
|
||||
@@ -1,26 +1,39 @@
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $2}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $3}'`
|
||||
AppVersionStrMajor=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $2}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $3}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $4}'`
|
||||
DevPostfix=''
|
||||
if [ "$DevChannel" != "0" ]; then
|
||||
DevPostfix='.dev'
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Win32/Deploy/deploy/$AppVersionStr$DevPostfix/tupdate$AppVersion" ]; then
|
||||
echo "tupdate$AppVersion not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tupdate$AppVersion" ]; then
|
||||
echo "tupdate$AppVersion not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Win32/Deploy/deploy/$AppVersionStr$DevPostfix/tportable.$AppVersionStr$DevPostfix.zip" ]; then
|
||||
echo "tportable.$AppVersionStr$DevPostfix.zip not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tportable.$AppVersionStr$DevPostfix.zip" ]; then
|
||||
echo "tportable.$AppVersionStr$DevPostfix.zip not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../Win32/Deploy/deploy/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.exe" ]; then
|
||||
echo "tsetup.$AppVersionStr$DevPostfix.exe not found!"
|
||||
exit 1
|
||||
if [ ! -f "./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.exe" ]; then
|
||||
echo "tsetup.$AppVersionStr$DevPostfix.exe not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStr$DevPostfix/tupdate$AppVersion /z/TBuild/tother/tsetup/
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStr$DevPostfix/tportable.$AppVersionStr$DevPostfix.zip /z/TBuild/tother/tsetup/
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.exe /z/TBuild/tother/tsetup/
|
||||
if [ ! -d "/z/TBuild/tother/tsetup/$AppVersionStrMajor" ]; then
|
||||
mkdir "/z/TBuild/tother/tsetup/$AppVersionStrMajor"
|
||||
fi
|
||||
|
||||
if [ ! -d "/z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix" ]; then
|
||||
mkdir "/z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix"
|
||||
fi
|
||||
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tupdate$AppVersion /z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tportable.$AppVersionStr$DevPostfix.zip /z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.exe /z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram.pdb /z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Updater.exe /z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../Win32/Deploy/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Updater.pdb /z/TBuild/tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
@@ -123,7 +123,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
@@ -142,7 +142,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
@@ -123,7 +123,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -140,7 +140,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
@@ -145,7 +145,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -162,7 +162,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;zlibstat.lib;libeay32MT.lib;Qt5Core.lib;LzmaLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;zlibstat.lib;libeay32MT.lib;Qt5Core.lib;qtpcre.lib;LzmaLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ImageHasSafeExceptionHandlers>
|
||||
</ImageHasSafeExceptionHandlers>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $2}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $3}'`
|
||||
AppVersionStrMajor=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $2}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $3}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $4}'`
|
||||
DevPostfix=''
|
||||
DevParam=''
|
||||
if [ "$DevChannel" != "0" ]; then
|
||||
@@ -8,12 +9,12 @@ if [ "$DevChannel" != "0" ]; then
|
||||
DevParam='-dev'
|
||||
fi
|
||||
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStr.dev" ]; then
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr.dev" ]; then
|
||||
echo "Deploy folder for version $AppVersionStr.dev already exists!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr" ]; then
|
||||
echo "Deploy folder for version $AppVersionStr already exists!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -40,12 +41,17 @@ echo "Packer done!"
|
||||
if [ ! -d "./../Linux/Release/deploy" ]; then
|
||||
mkdir "./../Linux/Release/deploy"
|
||||
fi
|
||||
|
||||
if [ ! -d "./../Linux/Release/deploy/$AppVersionStrMajor" ]; then
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor"
|
||||
fi
|
||||
|
||||
echo "Copying Telegram, Updater and tlinuxupd$AppVersion to deploy/$AppVersionStr$DevPostfix..";
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStr$DevPostfix/Telegram"
|
||||
mv ./../Linux/Release/Telegram ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/Updater ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/tlinuxupd$AppVersion ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/
|
||||
cd ./../Linux/Release/deploy/$AppVersionStr$DevPostfix && tar -cJvf tsetup.$AppVersionStr$DevPostfix.tar.xz Telegram/ && cd ./../../../../Telegram
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram"
|
||||
mv ./../Linux/Release/Telegram ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/Updater ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/tlinuxupd$AppVersion ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cd ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix && tar -cJvf tsetup.$AppVersionStr$DevPostfix.tar.xz Telegram/ && cd ./../../../../../Telegram
|
||||
echo "Version $AppVersionStr$DevPostfix prepared!";
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $2}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $3}'`
|
||||
AppVersionStrMajor=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $2}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $3}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $4}'`
|
||||
DevPostfix=''
|
||||
DevParam=''
|
||||
if [ "$DevChannel" != "0" ]; then
|
||||
@@ -8,12 +9,12 @@ if [ "$DevChannel" != "0" ]; then
|
||||
DevParam='-dev'
|
||||
fi
|
||||
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStr.dev" ]; then
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr.dev" ]; then
|
||||
echo "Deploy folder for version $AppVersionStr.dev already exists!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then
|
||||
if [ -d "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr" ]; then
|
||||
echo "Deploy folder for version $AppVersionStr already exists!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -40,12 +41,17 @@ echo "Packer done!"
|
||||
if [ ! -d "./../Linux/Release/deploy" ]; then
|
||||
mkdir "./../Linux/Release/deploy"
|
||||
fi
|
||||
|
||||
if [ ! -d "./../Linux/Release/deploy/$AppVersionStrMajor" ]; then
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor"
|
||||
fi
|
||||
|
||||
echo "Copying Telegram, Updater and tlinux32upd$AppVersion to deploy/$AppVersionStr$DevPostfix..";
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStr$DevPostfix/Telegram"
|
||||
mv ./../Linux/Release/Telegram ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/Updater ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/tlinux32upd$AppVersion ./../Linux/Release/deploy/$AppVersionStr$DevPostfix/
|
||||
cd ./../Linux/Release/deploy/$AppVersionStr$DevPostfix && tar -cJvf tsetup32.$AppVersionStr$DevPostfix.tar.xz Telegram/ && cd ./../../../../Telegram
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram"
|
||||
mv ./../Linux/Release/Telegram ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/Updater ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Linux/Release/tlinux32upd$AppVersion ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cd ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix && tar -cJvf tsetup32.$AppVersionStr$DevPostfix.tar.xz Telegram/ && cd ./../../../../../Telegram
|
||||
echo "Version $AppVersionStr$DevPostfix prepared!";
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $2}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $3}'`
|
||||
AppVersionStrMajor=`./Version.sh | awk -F " " '{print $1}'`
|
||||
AppVersion=`./Version.sh | awk -F " " '{print $2}'`
|
||||
AppVersionStr=`./Version.sh | awk -F " " '{print $3}'`
|
||||
DevChannel=`./Version.sh | awk -F " " '{print $4}'`
|
||||
DevPostfix=''
|
||||
DevParam=''
|
||||
if [ "$DevChannel" != "0" ]; then
|
||||
@@ -12,12 +13,12 @@ echo ""
|
||||
echo "Preparing version $AppVersionStr$DevPostfix.."
|
||||
echo ""
|
||||
|
||||
if [ -d "./../Mac/Release/deploy/$AppVersionStr.dev" ]; then
|
||||
if [ -d "./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr.dev" ]; then
|
||||
echo "Deploy folder for version $AppVersionStr.dev already exists!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "./../Mac/Release/deploy/$AppVersionStr" ]; then
|
||||
if [ -d "./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr" ]; then
|
||||
echo "Deploy folder for version $AppVersionStr already exists!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -73,19 +74,23 @@ hdiutil convert tsetup.dmg -format UDZO -imagekey zlib-level=9 -ov -o tsetup.$Ap
|
||||
cd ./../../Telegram
|
||||
cd ./../Mac/Release && ./Packer.app/Contents/MacOS/Packer -path Telegram.app -version $AppVersion $DevParam && cd ./../../Telegram
|
||||
|
||||
if [ ! -d "./../Mac/Release/deploy/" ]; then
|
||||
if [ ! -d "./../Mac/Release/deploy" ]; then
|
||||
mkdir "./../Mac/Release/deploy"
|
||||
fi
|
||||
|
||||
echo "Copying Telegram.app and tmacupd$AppVersion to deploy/$AppVersionStr..";
|
||||
mkdir "./../Mac/Release/deploy/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Mac/Release/deploy/$AppVersionStr$DevPostfix/Telegram"
|
||||
cp -r ./../Mac/Release/Telegram.app ./../Mac/Release/deploy/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Mac/Release/Telegram.app.dSYM ./../Mac/Release/deploy/$AppVersionStr$DevPostfix/
|
||||
if [ ! -d "./../Mac/Release/deploy/$AppVersionStrMajor" ]; then
|
||||
mkdir "./../Mac/Release/deploy/$AppVersionStrMajor"
|
||||
fi
|
||||
|
||||
echo "Copying Telegram.app and tmacupd$AppVersion to deploy/$AppVersionStrMajor/$AppVersionStr..";
|
||||
mkdir "./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram"
|
||||
cp -r ./../Mac/Release/Telegram.app ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram/
|
||||
mv ./../Mac/Release/Telegram.app.dSYM ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
rm ./../Mac/Release/Telegram.app/Contents/MacOS/Telegram
|
||||
rm ./../Mac/Release/Telegram.app/Contents/Frameworks/Updater
|
||||
rm -rf ./../Mac/Release/Telegram.app/Contents/_CodeSignature
|
||||
mv ./../Mac/Release/tmacupd$AppVersion ./../Mac/Release/deploy/$AppVersionStr$DevPostfix/
|
||||
mv ./../Mac/Release/tsetup.$AppVersionStr$DevPostfix.dmg ./../Mac/Release/deploy/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg
|
||||
mv ./../Mac/Release/tmacupd$AppVersion ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
mv ./../Mac/Release/tsetup.$AppVersionStr$DevPostfix.dmg ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg
|
||||
echo "Version $AppVersionStr$DevPostfix prepared!";
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
@echo OFF
|
||||
|
||||
set "AppVersion=8029"
|
||||
set "AppVersionStrSmall=0.8.29"
|
||||
set "AppVersionStr=0.8.29"
|
||||
set "AppVersionStrFull=0.8.29.0"
|
||||
set "AppVersionStrMajor=0.8"
|
||||
set "AppVersion=8039"
|
||||
set "AppVersionStrSmall=0.8.39"
|
||||
set "AppVersionStr=0.8.39"
|
||||
set "AppVersionStrFull=0.8.39.0"
|
||||
set "DevChannel=1"
|
||||
|
||||
if %DevChannel% neq 0 goto preparedev
|
||||
@@ -23,8 +24,8 @@ echo.
|
||||
echo Preparing version %AppVersionStr%%DevPostfix%..
|
||||
echo.
|
||||
|
||||
if exist ..\Win32\Deploy\deploy\%AppVersionStr%\ goto error_exist1
|
||||
if exist ..\Win32\Deploy\deploy\%AppVersionStr%.dev\ goto error_exist2
|
||||
if exist ..\Win32\Deploy\deploy\%AppVersionStrMajor%\%AppVersionStr%\ goto error_exist1
|
||||
if exist ..\Win32\Deploy\deploy\%AppVersionStrMajor%\%AppVersionStr%.dev\ goto error_exist2
|
||||
if exist ..\Win32\Deploy\tupdate%AppVersion% goto error_exist3
|
||||
|
||||
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"
|
||||
@@ -46,17 +47,18 @@ call Packer.exe -version %AppVersion% -path Telegram.exe -path Updater.exe %DevP
|
||||
if %errorlevel% neq 0 goto error1
|
||||
|
||||
if not exist deploy mkdir deploy
|
||||
mkdir deploy\%AppVersionStr%%DevPostfix%
|
||||
mkdir deploy\%AppVersionStr%%DevPostfix%\Telegram
|
||||
if not exist deploy\%AppVersionStrMajor% mkdir deploy\%AppVersionStrMajor%
|
||||
mkdir deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%
|
||||
mkdir deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\Telegram
|
||||
|
||||
move Telegram.exe deploy\%AppVersionStr%%DevPostfix%\Telegram\
|
||||
move Updater.exe deploy\%AppVersionStr%%DevPostfix%\
|
||||
move Telegram.pdb deploy\%AppVersionStr%%DevPostfix%\
|
||||
move Updater.pdb deploy\%AppVersionStr%%DevPostfix%\
|
||||
move tsetup.%AppVersionStr%%DevPostfix%.exe deploy\%AppVersionStr%%DevPostfix%\
|
||||
move tupdate%AppVersion% deploy\%AppVersionStr%%DevPostfix%\
|
||||
move Telegram.exe deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\Telegram\
|
||||
move Updater.exe deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\
|
||||
move Telegram.pdb deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\
|
||||
move Updater.pdb deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\
|
||||
move tsetup.%AppVersionStr%%DevPostfix%.exe deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\
|
||||
move tupdate%AppVersion% deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\
|
||||
|
||||
cd deploy\%AppVersionStr%%DevPostfix%
|
||||
cd deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%
|
||||
7z a -mx9 tportable.%AppVersionStr%%DevPostfix%.zip Telegram\
|
||||
if %errorlevel% neq 0 goto error2
|
||||
|
||||
@@ -64,11 +66,11 @@ echo .
|
||||
echo Version %AppVersionStr%%DevPostfix% is ready for deploy!
|
||||
echo .
|
||||
|
||||
cd ..\..\..\..\Telegram
|
||||
cd ..\..\..\..\..\Telegram
|
||||
goto eof
|
||||
|
||||
:error2
|
||||
cd ..\..
|
||||
cd ..\..\..
|
||||
:error1
|
||||
cd ..\..\Telegram
|
||||
echo ERROR occured!
|
||||
|
||||
@@ -166,11 +166,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_username_title" = "Change username";
|
||||
"lng_username_about" = "You can choose a username on Telegram.\nIf you do, other people will be able to find\nyou by this username and contact you\nwithout knowing your phone number.\n\nYou can use a-z, 0-9 and underscores.\nMinimum length is 5 characters.";
|
||||
"lng_username_invalid" = "This name is invalid.";
|
||||
"lng_username_occupied" = "This name is already occupied.";
|
||||
"lng_username_too_short" = "This name is too short.";
|
||||
"lng_username_bad_symbols" = "This name has bad symbols.";
|
||||
"lng_username_available" = "This name is available.";
|
||||
"lng_username_invalid" = "This username is invalid.";
|
||||
"lng_username_occupied" = "This username is already occupied.";
|
||||
"lng_username_too_short" = "This username is too short.";
|
||||
"lng_username_bad_symbols" = "This username has bad symbols.";
|
||||
"lng_username_available" = "This username is available.";
|
||||
"lng_username_not_found" = "User @{user} not found.";
|
||||
|
||||
"lng_settings_section_contact_info" = "Contact info";
|
||||
@@ -301,13 +301,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_connection_type" = "Connection type:";
|
||||
"lng_connection_auto_connecting" = "Default (connecting..)";
|
||||
"lng_connection_auto" = "Default ({type} used)";
|
||||
"lng_connection_http_proxy" = "HTTP with proxy";
|
||||
"lng_connection_tcp_proxy" = "TCP with proxy";
|
||||
"lng_connection_auto" = "Default ({transport} used)";
|
||||
"lng_connection_proxy_connecting" = "Connecting through proxy..";
|
||||
"lng_connection_proxy" = "{transport} with proxy";
|
||||
"lng_connection_header" = "Connection type";
|
||||
"lng_connection_auto_rb" = "Auto (TCP if available or HTTP)";
|
||||
"lng_connection_http_proxy_rb" = "HTTP with custom http-proxy";
|
||||
"lng_connection_tcp_proxy_rb" = "TCP with custom socks5-proxy";
|
||||
"lng_connection_try_ipv6" = "Try connecting through IPv6";
|
||||
"lng_connection_host_ph" = "Hostname";
|
||||
"lng_connection_port_ph" = "Port";
|
||||
"lng_connection_user_ph" = "Username";
|
||||
@@ -367,6 +368,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Files overview";
|
||||
"lng_profile_audios" = "{count:_not_used_|# voice message|# voice messages} »";
|
||||
"lng_profile_audios_header" = "Voice messages overview";
|
||||
"lng_profile_audio_files_header" = "Playlist";
|
||||
"lng_profile_show_all_types" = "Show all types";
|
||||
"lng_profile_copy_phone" = "Copy phone number";
|
||||
|
||||
@@ -601,7 +603,7 @@ Copyright (c) 2014 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_minor" = "— Bug fixes and other minor improvements";
|
||||
"lng_new_version_text" = "This new version includes support for bots using the new bot API, free for everyone. If you're an engineer, create your own bots for games, services or integrations.\n\nLearn more at {blog_link}";
|
||||
"lng_new_version_text" = "— Improved in-app media playback\n— Bug fixes and other minor improvements";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||
|
||||
|
||||
@@ -868,6 +868,8 @@ defaultTextStyle: textStyle {
|
||||
lineHeight: 0px;
|
||||
}
|
||||
serviceTextStyle: textStyle(defaultTextStyle) {
|
||||
lnkFlags: msgServiceFont;
|
||||
lnkOverFlags: font(fsize semibold underline);
|
||||
lnkColor: msgServiceColor;
|
||||
lnkDownColor: msgServiceColor;
|
||||
selectBg: msgServiceSelectBg;
|
||||
@@ -913,6 +915,8 @@ mediaDocOutImg: sprite(6px, 146px, 48px, 48px);
|
||||
mediaDocInImg: sprite(56px, 146px, 48px, 48px);
|
||||
mediaAudioOutImg: sprite(106px, 146px, 48px, 48px);
|
||||
mediaAudioInImg: sprite(156px, 146px, 48px, 48px);
|
||||
mediaMusicOutImg: sprite(322px, 345px, 48px, 48px);
|
||||
mediaMusicInImg: sprite(322px, 395px, 48px, 48px);
|
||||
mediaPlayOutImg: sprite(122px, 341px, 48px, 48px);
|
||||
mediaPlayInImg: sprite(172px, 341px, 48px, 48px);
|
||||
mediaPauseOutImg: sprite(222px, 341px, 48px, 48px);
|
||||
@@ -961,9 +965,9 @@ btnSend: flatButton(btnDefFlat) {
|
||||
width: -32px;
|
||||
height: 46px;
|
||||
|
||||
textTop: 13px;
|
||||
overTextTop: 13px;
|
||||
downTextTop: 14px;
|
||||
textTop: 12px;
|
||||
overTextTop: 12px;
|
||||
downTextTop: 13px;
|
||||
|
||||
font: font(16px);
|
||||
overFont: font(16px);
|
||||
@@ -985,26 +989,32 @@ btnAttachPhoto: iconedButton(btnAttachDocument) {
|
||||
}
|
||||
btnAttachEmoji: iconedButton(btnAttachDocument) {
|
||||
overBgColor: white;
|
||||
icon: sprite(363px, 344px, 21px, 22px);
|
||||
icon: sprite(374px, 344px, 21px, 22px);
|
||||
iconPos: point(6px, 12px);
|
||||
downIcon: sprite(363px, 344px, 21px, 22px);
|
||||
downIcon: sprite(374px, 344px, 21px, 22px);
|
||||
downIconPos: point(6px, 12px);
|
||||
|
||||
width: 33px;
|
||||
}
|
||||
btnBotKbShow: iconedButton(btnAttachEmoji) {
|
||||
icon: sprite(375px, 74px, 21px, 16px);
|
||||
iconPos: point(6px, 16px);
|
||||
downIcon: sprite(375px, 74px, 21px, 16px);
|
||||
downIconPos: point(6px, 16px);
|
||||
icon: sprite(375px, 74px, 21px, 21px);
|
||||
iconPos: point(6px, 12px);
|
||||
downIcon: sprite(375px, 74px, 21px, 21px);
|
||||
downIconPos: point(6px, 12px);
|
||||
}
|
||||
btnBotCmdStart: iconedButton(btnAttachEmoji) {
|
||||
icon: sprite(354px, 74px, 21px, 21px);
|
||||
iconPos: point(6px, 12px);
|
||||
downIcon: sprite(354px, 74px, 21px, 21px);
|
||||
downIconPos: point(6px, 12px);
|
||||
}
|
||||
btnBotKbHide: iconedButton(btnAttachEmoji) {
|
||||
icon: sprite(352px, 74px, 23px, 14px);
|
||||
icon: sprite(373px, 95px, 23px, 14px);
|
||||
iconPos: point(5px, 17px);
|
||||
downIcon: sprite(352px, 74px, 23px, 14px);
|
||||
downIcon: sprite(373px, 95px, 23px, 14px);
|
||||
downIconPos: point(5px, 17px);
|
||||
}
|
||||
btnRecordAudio: sprite(363px, 366px, 16px, 24px);
|
||||
btnRecordAudio: sprite(379px, 390px, 16px, 24px);
|
||||
btnRecordAudioActive: sprite(379px, 366px, 16px, 24px);
|
||||
recordSignalColor: #f17077;
|
||||
recordSignalMin: 5px;
|
||||
@@ -1140,7 +1150,7 @@ notifyTextTop: 7px;
|
||||
notifySlowHideFunc: transition(easeInCirc);
|
||||
notifyWaitShortHide: 0;
|
||||
notifyWaitLongHide: 20000;
|
||||
notifyFastAnim: 100;
|
||||
notifyFastAnim: 150;
|
||||
notifyFastAnimFunc: transition(linear);
|
||||
notifyWidth: 316px;
|
||||
notifyHeight: 80px;
|
||||
@@ -1527,30 +1537,22 @@ stickersScroll: flatScroll(newScroll) {
|
||||
emojiScroll: flatScroll(newScroll) {
|
||||
deltat: 48px;
|
||||
}
|
||||
emojiRecent: sprite(0px, 196px, 21px, 22px);
|
||||
emojiRecentOver: sprite(287px, 220px, 21px, 22px);
|
||||
emojiRecentActive: sprite(287px, 242px, 21px, 22px);
|
||||
emojiPeople: sprite(21px, 196px, 21px, 22px);
|
||||
emojiPeopleOver: sprite(308px, 220px, 21px, 22px);
|
||||
emojiPeopleActive: sprite(308px, 242px, 21px, 22px);
|
||||
emojiNature: sprite(42px, 196px, 21px, 22px);
|
||||
emojiNatureOver: sprite(245px, 264px, 21px, 22px);
|
||||
emojiRecentOver: sprite(0px, 196px, 21px, 22px);
|
||||
emojiRecentActive: sprite(245px, 264px, 21px, 22px);
|
||||
emojiPeopleOver: sprite(21px, 196px, 21px, 22px);
|
||||
emojiPeopleActive: sprite(266px, 264px, 21px, 22px);
|
||||
emojiNatureOver: sprite(42px, 196px, 21px, 22px);
|
||||
emojiNatureActive: sprite(245px, 286px, 21px, 22px);
|
||||
emojiFood: sprite(63px, 196px, 21px, 22px);
|
||||
emojiFoodOver: sprite(266px, 264px, 21px, 22px);
|
||||
emojiFoodOver: sprite(63px, 196px, 21px, 22px);
|
||||
emojiFoodActive: sprite(266px, 286px, 21px, 22px);
|
||||
emojiCelebration: sprite(84px, 196px, 21px, 22px);
|
||||
emojiCelebrationOver: sprite(287px, 264px, 21px, 22px);
|
||||
emojiCelebrationOver: sprite(84px, 196px, 21px, 22px);
|
||||
emojiCelebrationActive: sprite(287px, 286px, 21px, 22px);
|
||||
emojiActivity: sprite(126px, 196px, 21px, 22px);
|
||||
emojiActivityOver: sprite(321px, 344px, 21px, 22px);
|
||||
emojiActivityActive: sprite(321px, 366px, 21px, 22px);
|
||||
emojiTravel: sprite(105px, 196px, 21px, 22px);
|
||||
emojiTravelOver: sprite(308px, 264px, 21px, 22px);
|
||||
emojiActivityOver: sprite(126px, 196px, 21px, 22px);
|
||||
emojiActivityActive: sprite(287px, 264px, 21px, 22px);
|
||||
emojiTravelOver: sprite(105px, 196px, 21px, 22px);
|
||||
emojiTravelActive: sprite(308px, 286px, 21px, 22px);
|
||||
emojiObjects: sprite(147px, 196px, 21px, 22px);
|
||||
emojiObjectsOver: sprite(342px, 344px, 21px, 22px);
|
||||
emojiObjectsActive: sprite(342px, 366px, 21px, 22px);
|
||||
emojiObjectsOver: sprite(147px, 196px, 21px, 22px);
|
||||
emojiObjectsActive: sprite(308px, 264px, 21px, 22px);
|
||||
|
||||
emojiPanCategories: #f7f7f7;
|
||||
|
||||
@@ -1559,7 +1561,7 @@ rbEmoji: flatCheckbox {
|
||||
bgColor: emojiPanCategories;
|
||||
disColor: emojiPanCategories;
|
||||
|
||||
width: 36px;
|
||||
width: 42px;
|
||||
height: 46px;
|
||||
|
||||
textTop: 0px;
|
||||
@@ -1570,7 +1572,7 @@ rbEmoji: flatCheckbox {
|
||||
cursor: cursor(pointer);
|
||||
|
||||
disabledCursor: cursor(default);
|
||||
imagePos: point(8px, 12px);
|
||||
imagePos: point(11px, 12px);
|
||||
}
|
||||
rbEmojiRecent: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiRecentOver;
|
||||
@@ -1636,16 +1638,17 @@ rbEmojiObjects: flatCheckbox(rbEmoji) {
|
||||
disImageRect: emojiObjectsOver;
|
||||
chkDisImageRect: emojiObjectsActive;
|
||||
}
|
||||
emojiPanPadding: 10px;
|
||||
emojiPanSize: size(39px, 35px);
|
||||
emojiPanFullSize: size(300px, 321px);
|
||||
emojiPanPadding: 12px;
|
||||
emojiPanSize: size(45px, 41px);
|
||||
emojiPanWidth: 345px;
|
||||
emojiPanMaxHeight: 366px;
|
||||
emojiPanDuration: 200;
|
||||
emojiPanHover: #f0f4f7;
|
||||
|
||||
emojiPanHeader: 42px;
|
||||
emojiPanHeaderFont: font(fsize semibold);
|
||||
emojiPanHeaderColor: #999;
|
||||
emojiPanHeaderLeft: 17px;
|
||||
emojiPanHeaderLeft: 22px;
|
||||
emojiPanHeaderTop: 12px;
|
||||
emojiPanHeaderBg: #fffffff2;
|
||||
|
||||
@@ -1659,7 +1662,7 @@ emojiSwitchStickers: sprite(318px, 328px, 8px, 12px);
|
||||
emojiSwitchEmoji: sprite(310px, 328px, 8px, 12px);
|
||||
emojiSwitchColor: #42a8db;
|
||||
|
||||
stickerPanSize: size(55px, 55px);
|
||||
stickerPanSize: size(64px, 64px);
|
||||
stickerPanPadding: 11px;
|
||||
stickerPanDelete: sprite(123px, 132px, 12px, 12px);
|
||||
stickerPanDeleteOpacity: 0.5;
|
||||
@@ -1718,11 +1721,11 @@ mvControlMargin: 0px;
|
||||
mvControlSize: 90px;
|
||||
mvIconSize: size(60px, 56px);
|
||||
|
||||
mvLeft: sprite(320px, 400px, 12px, 22px);
|
||||
mvRight: sprite(332px, 400px, 12px, 22px);
|
||||
mvClose: sprite(344px, 400px, 18px, 18px);
|
||||
mvSave: sprite(362px, 400px, 14px, 19px);
|
||||
mvMore: sprite(376px, 400px, 5px, 21px);
|
||||
mvLeft: sprite(320px, 445px, 12px, 22px);
|
||||
mvRight: sprite(332px, 445px, 12px, 22px);
|
||||
mvClose: sprite(344px, 445px, 18px, 18px);
|
||||
mvSave: sprite(362px, 445px, 14px, 19px);
|
||||
mvMore: sprite(376px, 445px, 5px, 21px);
|
||||
|
||||
mvDropdown: dropdown(dropdownDef) {
|
||||
shadow: sprite(0px, 0px, 0px, 0px);
|
||||
@@ -1961,3 +1964,36 @@ webPagePhotoSize: 100px;
|
||||
webPagePhotoDelta: 8px;
|
||||
|
||||
botDescSkip: 8px;
|
||||
|
||||
suppressAll: 0.2;
|
||||
suppressSong: 0.05;
|
||||
|
||||
playerHeight: 44px;
|
||||
playerBg: #e4e9ef;
|
||||
playerFg: #54748f;
|
||||
playerTimeFg: #a4afba;
|
||||
playerLineHeight: 3px;
|
||||
playerMoverSize: size(2px, 7px);
|
||||
playerLineActive: #6389a8;
|
||||
playerLineInactive: #bac7d4;
|
||||
playerSkip: 8px;
|
||||
playerNameStyle: textStyle(defaultTextStyle) {
|
||||
lnkColor: #6389a8;
|
||||
lnkDownColor: #6389a8;
|
||||
lnkFlags: font(fsize semibold);
|
||||
lnkOverFlags: font(fsize semibold);
|
||||
}
|
||||
playerPlay: sprite(377px, 109px, 19px, 22px);
|
||||
playerPause: sprite(379px, 131px, 17px, 20px);
|
||||
playerNext: sprite(374px, 151px, 22px, 14px);
|
||||
playerPrev: sprite(374px, 165px, 22px, 14px);
|
||||
playerClose: sprite(361px, 97px, 12px, 12px);
|
||||
playerFull: sprite(365px, 109px, 12px, 12px);
|
||||
playerRepeat: sprite(365px, 121px, 12px, 14px);
|
||||
playerVolume: sprite(352px, 179px, 44px, 12px);
|
||||
playerInactiveOpacity: 0.8;
|
||||
playerUnavailableOpacity: 0.3;
|
||||
playerDuration: 200;
|
||||
|
||||
playlistHoverBg: #f2f2f2;
|
||||
playlistPadding: 10px;
|
||||
|
||||
@@ -23,6 +23,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QDataStream>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
@@ -83,91 +83,6 @@ void ApiWrap::requestReplyTo(HistoryReply *reply, MsgId to) {
|
||||
if (!req.req) _replyToTimer.start(1);
|
||||
}
|
||||
|
||||
void ApiWrap::requestFullPeer(PeerData *peer) {
|
||||
if (!peer || _fullRequests.contains(peer)) return;
|
||||
mtpRequestId req;
|
||||
if (peer->chat) {
|
||||
req = MTP::send(MTPmessages_GetFullChat(MTP_int(App::chatFromPeer(peer->id))), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
|
||||
} else {
|
||||
req = MTP::send(MTPusers_GetFullUser(peer->asUser()->inputUser), rpcDone(&ApiWrap::gotUserFull, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
|
||||
}
|
||||
_fullRequests.insert(peer, req);
|
||||
}
|
||||
|
||||
void ApiWrap::requestWebPageDelayed(WebPageData *page) {
|
||||
if (page->pendingTill <= 0) return;
|
||||
_webPagesPending.insert(page, 0);
|
||||
int32 left = (page->pendingTill - unixtime()) * 1000;
|
||||
if (!_webPagesTimer.isActive() || left <= _webPagesTimer.remainingTime()) {
|
||||
_webPagesTimer.start((left < 0 ? 0 : left) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::clearWebPageRequest(WebPageData *page) {
|
||||
_webPagesPending.remove(page);
|
||||
if (_webPagesPending.isEmpty() && _webPagesTimer.isActive()) _webPagesTimer.stop();
|
||||
}
|
||||
|
||||
void ApiWrap::clearWebPageRequests() {
|
||||
_webPagesPending.clear();
|
||||
_webPagesTimer.stop();
|
||||
}
|
||||
|
||||
void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) {
|
||||
const MTPDmessages_chatFull &d(result.c_messages_chatFull());
|
||||
const MTPDchatFull &f(d.vfull_chat.c_chatFull());
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
App::feedParticipants(f.vparticipants);
|
||||
const QVector<MTPBotInfo> &v(f.vbot_info.c_vector().v);
|
||||
for (QVector<MTPBotInfo>::const_iterator i = v.cbegin(), e = v.cend(); i < e; ++i) {
|
||||
switch (i->type()) {
|
||||
case mtpc_botInfo: {
|
||||
const MTPDbotInfo &b(i->c_botInfo());
|
||||
UserData *user = App::userLoaded(b.vuser_id.v);
|
||||
if (user) {
|
||||
user->setBotInfo(*i);
|
||||
emit fullPeerUpdated(user);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
PhotoData *photo = App::feedPhoto(f.vchat_photo);
|
||||
ChatData *chat = peer->asChat();
|
||||
if (chat) {
|
||||
if (photo) {
|
||||
chat->photoId = photo->id;
|
||||
photo->chat = chat;
|
||||
}
|
||||
chat->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
|
||||
}
|
||||
|
||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
||||
|
||||
_fullRequests.remove(peer);
|
||||
emit fullPeerUpdated(peer);
|
||||
}
|
||||
|
||||
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) {
|
||||
const MTPDuserFull &d(result.c_userFull());
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
||||
App::feedPhoto(d.vprofile_photo);
|
||||
App::feedUserLink(MTP_int(App::userFromPeer(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link);
|
||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
|
||||
|
||||
peer->asUser()->setBotInfo(d.vbot_info);
|
||||
|
||||
_fullRequests.remove(peer);
|
||||
emit fullPeerUpdated(peer);
|
||||
}
|
||||
|
||||
bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
_fullRequests.remove(peer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::resolveReplyTo() {
|
||||
if (_replyToRequests.isEmpty()) return;
|
||||
|
||||
@@ -186,34 +101,6 @@ void ApiWrap::resolveReplyTo() {
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::resolveWebPages() {
|
||||
QVector<MTPint> ids;
|
||||
const WebPageItems &items(App::webPageItems());
|
||||
ids.reserve(_webPagesPending.size());
|
||||
int32 t = unixtime(), m = INT_MAX;
|
||||
for (WebPagesPending::const_iterator i = _webPagesPending.cbegin(), e = _webPagesPending.cend(); i != e; ++i) {
|
||||
if (i.value()) continue;
|
||||
if (i.key()->pendingTill <= t) {
|
||||
WebPageItems::const_iterator j = items.constFind(i.key());
|
||||
if (j != items.cend() && !j.value().isEmpty()) {
|
||||
ids.push_back(MTP_int(j.value().begin().key()->id));
|
||||
}
|
||||
} else {
|
||||
m = qMin(m, i.key()->pendingTill - t);
|
||||
}
|
||||
}
|
||||
if (!ids.isEmpty()) {
|
||||
mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotWebPages));
|
||||
for (WebPagesPending::iterator i = _webPagesPending.begin(); i != _webPagesPending.cend(); ++i) {
|
||||
if (i.value()) continue;
|
||||
if (i.key()->pendingTill <= t) {
|
||||
i.value() = req;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m < INT_MAX) _webPagesTimer.start(m * 1000);
|
||||
}
|
||||
|
||||
void ApiWrap::gotReplyTo(const MTPmessages_Messages &msgs, mtpRequestId req) {
|
||||
switch (msgs.type()) {
|
||||
case mtpc_messages_messages:
|
||||
@@ -244,6 +131,298 @@ void ApiWrap::gotReplyTo(const MTPmessages_Messages &msgs, mtpRequestId req) {
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::requestFullPeer(PeerData *peer) {
|
||||
if (!peer || _fullPeerRequests.contains(peer)) return;
|
||||
|
||||
mtpRequestId req;
|
||||
if (peer->chat) {
|
||||
req = MTP::send(MTPmessages_GetFullChat(MTP_int(App::chatFromPeer(peer->id))), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer));
|
||||
} else {
|
||||
req = MTP::send(MTPusers_GetFullUser(peer->asUser()->inputUser), rpcDone(&ApiWrap::gotUserFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer));
|
||||
}
|
||||
_fullPeerRequests.insert(peer, req);
|
||||
}
|
||||
|
||||
void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) {
|
||||
const MTPDmessages_chatFull &d(result.c_messages_chatFull());
|
||||
const MTPDchatFull &f(d.vfull_chat.c_chatFull());
|
||||
|
||||
const QVector<MTPChat> &vc(d.vchats.c_vector().v);
|
||||
bool badVersion = (!vc.isEmpty() && vc.at(0).type() == mtpc_chat && vc.at(0).c_chat().vversion.v < peer->asChat()->version);
|
||||
|
||||
App::feedUsers(d.vusers, false);
|
||||
App::feedChats(d.vchats, false);
|
||||
App::feedParticipants(f.vparticipants, false, false);
|
||||
const QVector<MTPBotInfo> &v(f.vbot_info.c_vector().v);
|
||||
for (QVector<MTPBotInfo>::const_iterator i = v.cbegin(), e = v.cend(); i < e; ++i) {
|
||||
switch (i->type()) {
|
||||
case mtpc_botInfo: {
|
||||
const MTPDbotInfo &b(i->c_botInfo());
|
||||
UserData *user = App::userLoaded(b.vuser_id.v);
|
||||
if (user) {
|
||||
user->setBotInfo(*i);
|
||||
App::clearPeerUpdated(user);
|
||||
emit fullPeerUpdated(user);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
PhotoData *photo = App::feedPhoto(f.vchat_photo);
|
||||
ChatData *chat = peer->asChat();
|
||||
if (chat) {
|
||||
if (photo) {
|
||||
chat->photoId = photo->id;
|
||||
photo->chat = chat;
|
||||
} else {
|
||||
chat->photoId = 0;
|
||||
}
|
||||
chat->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
|
||||
}
|
||||
|
||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
||||
|
||||
_fullPeerRequests.remove(peer);
|
||||
if (badVersion) {
|
||||
peer->asChat()->version = vc.at(0).c_chat().vversion.v;
|
||||
requestPeer(peer);
|
||||
}
|
||||
App::clearPeerUpdated(peer);
|
||||
emit fullPeerUpdated(peer);
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) {
|
||||
const MTPDuserFull &d(result.c_userFull());
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
||||
App::feedPhoto(d.vprofile_photo);
|
||||
App::feedUserLink(MTP_int(App::userFromPeer(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link, false);
|
||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
|
||||
|
||||
peer->asUser()->setBotInfo(d.vbot_info);
|
||||
|
||||
_fullPeerRequests.remove(peer);
|
||||
App::clearPeerUpdated(peer);
|
||||
emit fullPeerUpdated(peer);
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
bool ApiWrap::gotPeerFullFailed(PeerData *peer, const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
_fullPeerRequests.remove(peer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::requestPeer(PeerData *peer) {
|
||||
if (!peer || _fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) return;
|
||||
|
||||
mtpRequestId req;
|
||||
if (peer->chat) {
|
||||
req = MTP::send(MTPmessages_GetChats(MTP_vector<MTPint>(1, MTP_int(App::chatFromPeer(peer->id)))), rpcDone(&ApiWrap::gotChat, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
|
||||
} else {
|
||||
req = MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(1, peer->asUser()->inputUser)), rpcDone(&ApiWrap::gotUser, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
|
||||
}
|
||||
_peerRequests.insert(peer, req);
|
||||
}
|
||||
|
||||
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
||||
_peerRequests.remove(peer);
|
||||
|
||||
if (result.type() == mtpc_messages_chats) {
|
||||
const QVector<MTPChat> &v(result.c_messages_chats().vchats.c_vector().v);
|
||||
bool badVersion = (!v.isEmpty() && v.at(0).type() == mtpc_chat && v.at(0).c_chat().vversion.v < peer->asChat()->version);
|
||||
ChatData *chat = App::feedChats(result.c_messages_chats().vchats);
|
||||
if (chat == peer) {
|
||||
if (badVersion) {
|
||||
peer->asChat()->version = v.at(0).c_chat().vversion.v;
|
||||
requestPeer(peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::gotUser(PeerData *peer, const MTPVector<MTPUser> &result) {
|
||||
_peerRequests.remove(peer);
|
||||
|
||||
UserData *user = App::feedUsers(result);
|
||||
if (user == peer) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
_peerRequests.remove(peer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::scheduleStickerSetRequest(uint64 setId, uint64 access) {
|
||||
if (!_stickerSetRequests.contains(setId)) {
|
||||
_stickerSetRequests.insert(setId, qMakePair(access, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::requestStickerSets() {
|
||||
for (QMap<uint64, QPair<uint64, mtpRequestId> >::iterator i = _stickerSetRequests.begin(), j = i, e = _stickerSetRequests.end(); i != e; i = j) {
|
||||
if (i.value().second) continue;
|
||||
|
||||
++j;
|
||||
int32 wait = (j == e) ? 0 : 10;
|
||||
i.value().second = MTP::send(MTPmessages_GetStickerSet(MTP_inputStickerSetID(MTP_long(i.key()), MTP_long(i.value().first))), rpcDone(&ApiWrap::gotStickerSet, i.key()), rpcFail(&ApiWrap::gotStickerSetFail, i.key()), 0, wait);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result) {
|
||||
_stickerSetRequests.remove(setId);
|
||||
|
||||
if (result.type() != mtpc_messages_stickerSet) return;
|
||||
const MTPDmessages_stickerSet &d(result.c_messages_stickerSet());
|
||||
|
||||
if (d.vset.type() != mtpc_stickerSet) return;
|
||||
const MTPDstickerSet &s(d.vset.c_stickerSet());
|
||||
|
||||
StickerSets &sets(cRefStickerSets());
|
||||
StickerSets::iterator it = sets.find(setId);
|
||||
if (it == sets.cend()) return;
|
||||
|
||||
it->access = s.vaccess_hash.v;
|
||||
it->hash = s.vhash.v;
|
||||
it->shortName = qs(s.vshort_name);
|
||||
QString title = qs(s.vtitle);
|
||||
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;
|
||||
|
||||
const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v);
|
||||
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
||||
|
||||
QSet<DocumentData*> found;
|
||||
int32 wasCount = -1;
|
||||
for (int32 i = 0, l = d_docs.size(); i != l; ++i) {
|
||||
DocumentData *doc = App::feedDocument(d_docs.at(i));
|
||||
if (!doc || !doc->sticker()) continue;
|
||||
|
||||
if (wasCount < 0) wasCount = it->stickers.size();
|
||||
if (it->stickers.indexOf(doc) < 0) {
|
||||
it->stickers.push_back(doc);
|
||||
} else {
|
||||
found.insert(doc);
|
||||
}
|
||||
|
||||
if (custom != sets.cend()) {
|
||||
int32 index = custom->stickers.indexOf(doc);
|
||||
if (index >= 0) {
|
||||
custom->stickers.removeAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (custom != sets.cend() && custom->stickers.isEmpty()) {
|
||||
sets.erase(custom);
|
||||
custom = sets.end();
|
||||
}
|
||||
|
||||
bool writeRecent = false;
|
||||
RecentStickerPack &recent(cGetRecentStickers());
|
||||
|
||||
if (wasCount < 0) { // no stickers received
|
||||
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
||||
if (it->stickers.indexOf(i->first) >= 0) {
|
||||
i = recent.erase(i);
|
||||
writeRecent = true;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
cRefStickerSetsOrder().removeOne(setId);
|
||||
sets.erase(it);
|
||||
} else {
|
||||
for (int32 j = 0, l = wasCount; j < l;) {
|
||||
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) {
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
|
||||
Local::writeStickers();
|
||||
|
||||
if (App::main()) emit App::main()->stickersUpdated();
|
||||
}
|
||||
|
||||
bool ApiWrap::gotStickerSetFail(uint64 setId, const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
_stickerSetRequests.remove(setId);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApiWrap::requestWebPageDelayed(WebPageData *page) {
|
||||
if (page->pendingTill <= 0) return;
|
||||
_webPagesPending.insert(page, 0);
|
||||
int32 left = (page->pendingTill - unixtime()) * 1000;
|
||||
if (!_webPagesTimer.isActive() || left <= _webPagesTimer.remainingTime()) {
|
||||
_webPagesTimer.start((left < 0 ? 0 : left) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::clearWebPageRequest(WebPageData *page) {
|
||||
_webPagesPending.remove(page);
|
||||
if (_webPagesPending.isEmpty() && _webPagesTimer.isActive()) _webPagesTimer.stop();
|
||||
}
|
||||
|
||||
void ApiWrap::clearWebPageRequests() {
|
||||
_webPagesPending.clear();
|
||||
_webPagesTimer.stop();
|
||||
}
|
||||
|
||||
void ApiWrap::resolveWebPages() {
|
||||
QVector<MTPint> ids;
|
||||
const WebPageItems &items(App::webPageItems());
|
||||
ids.reserve(_webPagesPending.size());
|
||||
int32 t = unixtime(), m = INT_MAX;
|
||||
for (WebPagesPending::const_iterator i = _webPagesPending.cbegin(), e = _webPagesPending.cend(); i != e; ++i) {
|
||||
if (i.value()) continue;
|
||||
if (i.key()->pendingTill <= t) {
|
||||
WebPageItems::const_iterator j = items.constFind(i.key());
|
||||
if (j != items.cend() && !j.value().isEmpty()) {
|
||||
ids.push_back(MTP_int(j.value().begin().key()->id));
|
||||
}
|
||||
} else {
|
||||
m = qMin(m, i.key()->pendingTill - t);
|
||||
}
|
||||
}
|
||||
if (!ids.isEmpty()) {
|
||||
mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotWebPages));
|
||||
for (WebPagesPending::iterator i = _webPagesPending.begin(); i != _webPagesPending.cend(); ++i) {
|
||||
if (i.value()) continue;
|
||||
if (i.key()->pendingTill <= t) {
|
||||
i.value() = req;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m < INT_MAX) _webPagesTimer.start(m * 1000);
|
||||
}
|
||||
|
||||
void ApiWrap::gotWebPages(const MTPmessages_Messages &msgs, mtpRequestId req) {
|
||||
const QVector<MTPMessage> *v = 0;
|
||||
switch (msgs.type()) {
|
||||
|
||||
@@ -31,11 +31,15 @@ public:
|
||||
void requestReplyTo(HistoryReply *reply, MsgId to);
|
||||
|
||||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
|
||||
void requestWebPageDelayed(WebPageData *page);
|
||||
void clearWebPageRequest(WebPageData *page);
|
||||
void clearWebPageRequests();
|
||||
|
||||
void scheduleStickerSetRequest(uint64 setId, uint64 access);
|
||||
void requestStickerSets();
|
||||
|
||||
~ApiWrap();
|
||||
|
||||
signals:
|
||||
@@ -62,13 +66,22 @@ private:
|
||||
|
||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||
void gotUserFull(PeerData *peer, const MTPUserFull &result);
|
||||
bool gotPeerFullFailed(PeerData *peer, const RPCError &err);
|
||||
typedef QMap<PeerData*, mtpRequestId> PeerRequests;
|
||||
PeerRequests _fullPeerRequests;
|
||||
|
||||
void gotChat(PeerData *peer, const MTPmessages_Chats &result);
|
||||
void gotUser(PeerData *peer, const MTPVector<MTPUser> &result);
|
||||
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
||||
typedef QMap<PeerData*, mtpRequestId> FullRequests;
|
||||
FullRequests _fullRequests;
|
||||
PeerRequests _peerRequests;
|
||||
|
||||
void gotWebPages(const MTPmessages_Messages &result, mtpRequestId req);
|
||||
typedef QMap<WebPageData*, mtpRequestId> WebPagesPending;
|
||||
WebPagesPending _webPagesPending;
|
||||
SingleTimer _webPagesTimer;
|
||||
|
||||
QMap<uint64, QPair<uint64, mtpRequestId> > _stickerSetRequests;
|
||||
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
|
||||
bool gotStickerSetFail(uint64 setId, const RPCError &error);
|
||||
|
||||
};
|
||||
|
||||
@@ -37,6 +37,9 @@ namespace {
|
||||
typedef QMap<PeerData*, bool> MutedPeers;
|
||||
MutedPeers mutedPeers;
|
||||
|
||||
typedef QMap<PeerData*, bool> UpdatedPeers;
|
||||
UpdatedPeers updatedPeers;
|
||||
|
||||
typedef QHash<PhotoId, PhotoData*> PhotosData;
|
||||
PhotosData photosData;
|
||||
|
||||
@@ -312,7 +315,11 @@ namespace App {
|
||||
return lng_status_lastseen_date(lt_date, dOnline.date().toString(qsl("dd.MM.yy")));
|
||||
}
|
||||
|
||||
bool onlineColorUse(int32 online, int32 now) {
|
||||
bool onlineColorUse(UserData *user, int32 now) {
|
||||
if (isServiceUser(user->id) || user->botInfo) {
|
||||
return false;
|
||||
}
|
||||
int32 online = user->onlineTill;
|
||||
if (online <= 0) {
|
||||
switch (online) {
|
||||
case 0:
|
||||
@@ -326,7 +333,7 @@ namespace App {
|
||||
return (online > now);
|
||||
}
|
||||
|
||||
UserData *feedUsers(const MTPVector<MTPUser> &users) {
|
||||
UserData *feedUsers(const MTPVector<MTPUser> &users, bool emitPeerUpdated) {
|
||||
UserData *data = 0;
|
||||
const QVector<MTPUser> &v(users.c_vector().v);
|
||||
for (QVector<MTPUser>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
||||
@@ -424,19 +431,25 @@ namespace App {
|
||||
if (data->contact < 0 && !data->phone.isEmpty() && int32(data->id & 0xFFFFFFFF) != MTP::authedId()) {
|
||||
data->contact = 0;
|
||||
}
|
||||
if (data->contact > 0 && !wasContact) {
|
||||
App::main()->addNewContact(data->id & 0xFFFFFFFF, false);
|
||||
} else if (wasContact && data->contact <= 0) {
|
||||
App::main()->removeContact(data);
|
||||
}
|
||||
if (App::main()) {
|
||||
if (data->contact > 0 && !wasContact) {
|
||||
App::main()->addNewContact(data->id & 0xFFFFFFFF, false);
|
||||
} else if (wasContact && data->contact <= 0) {
|
||||
App::main()->removeContact(data);
|
||||
}
|
||||
|
||||
if (App::main()) App::main()->peerUpdated(data);
|
||||
if (emitPeerUpdated) {
|
||||
App::main()->peerUpdated(data);
|
||||
} else {
|
||||
markPeerUpdated(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
ChatData *feedChats(const MTPVector<MTPChat> &chats) {
|
||||
ChatData *feedChats(const MTPVector<MTPChat> &chats, bool emitPeerUpdated) {
|
||||
ChatData *data = 0;
|
||||
const QVector<MTPChat> &v(chats.c_vector().v);
|
||||
for (QVector<MTPChat>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
||||
@@ -503,24 +516,31 @@ namespace App {
|
||||
data->loaded = true;
|
||||
data->updateName(title.trimmed(), QString(), QString());
|
||||
|
||||
if (App::main()) App::main()->peerUpdated(data);
|
||||
if (App::main()) {
|
||||
if (emitPeerUpdated) {
|
||||
App::main()->peerUpdated(data);
|
||||
} else {
|
||||
markPeerUpdated(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos) {
|
||||
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos, bool emitPeerUpdated) {
|
||||
ChatData *chat = 0;
|
||||
switch (p.type()) {
|
||||
case mtpc_chatParticipantsForbidden: {
|
||||
const MTPDchatParticipantsForbidden &d(p.c_chatParticipantsForbidden());
|
||||
ChatData *chat = App::chat(d.vchat_id.v);
|
||||
chat = App::chat(d.vchat_id.v);
|
||||
chat->count = -1;
|
||||
if (App::main()) App::main()->peerUpdated(chat);
|
||||
} break;
|
||||
|
||||
case mtpc_chatParticipants: {
|
||||
const MTPDchatParticipants &d(p.c_chatParticipants());
|
||||
ChatData *chat = App::chat(d.vchat_id.v);
|
||||
chat = App::chat(d.vchat_id.v);
|
||||
chat->admin = d.vadmin_id.v;
|
||||
if (chat->version <= d.vversion.v) {
|
||||
if (!requestBotInfos || chat->version <= d.vversion.v) { // !requestBotInfos is true on getFullChat result
|
||||
chat->version = d.vversion.v;
|
||||
const QVector<MTPChatParticipant> &v(d.vparticipants.c_vector().v);
|
||||
chat->count = v.size();
|
||||
@@ -564,13 +584,19 @@ namespace App {
|
||||
if (App::main()) App::main()->updateBotKeyboard();
|
||||
}
|
||||
}
|
||||
if (App::main()) App::main()->peerUpdated(chat);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
if (chat && App::main()) {
|
||||
if (emitPeerUpdated) {
|
||||
App::main()->peerUpdated(chat);
|
||||
} else {
|
||||
markPeerUpdated(chat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d) {
|
||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated) {
|
||||
ChatData *chat = App::chat(d.vchat_id.v);
|
||||
if (chat->version <= d.vversion.v && chat->count >= 0) {
|
||||
chat->version = d.vversion.v;
|
||||
@@ -597,11 +623,17 @@ namespace App {
|
||||
chat->botStatus = 0;
|
||||
chat->count++;
|
||||
}
|
||||
if (App::main()) App::main()->peerUpdated(chat);
|
||||
if (App::main()) {
|
||||
if (emitPeerUpdated) {
|
||||
App::main()->peerUpdated(chat);
|
||||
} else {
|
||||
markPeerUpdated(chat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d) {
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated) {
|
||||
ChatData *chat = App::chat(d.vchat_id.v);
|
||||
if (chat->version <= d.vversion.v && chat->count > 0) {
|
||||
chat->version = d.vversion.v;
|
||||
@@ -641,7 +673,13 @@ namespace App {
|
||||
chat->botStatus = 0;
|
||||
chat->count--;
|
||||
}
|
||||
if (App::main()) App::main()->peerUpdated(chat);
|
||||
if (App::main()) {
|
||||
if (emitPeerUpdated) {
|
||||
App::main()->peerUpdated(chat);
|
||||
} else {
|
||||
markPeerUpdated(chat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,6 +775,9 @@ namespace App {
|
||||
History *h = App::historyLoaded(peer);
|
||||
if (h) {
|
||||
h->outboxRead(upTo);
|
||||
if (!h->peer->chat) {
|
||||
h->peer->asUser()->madeAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -757,23 +798,30 @@ namespace App {
|
||||
}
|
||||
}
|
||||
|
||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links) {
|
||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links, bool emitPeerUpdated) {
|
||||
const QVector<MTPcontacts_Link> &v(links.c_vector().v);
|
||||
for (QVector<MTPcontacts_Link>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
||||
const MTPDcontacts_link &dv(i->c_contacts_link());
|
||||
feedUsers(MTP_vector<MTPUser>(1, dv.vuser));
|
||||
UserData *user = feedUsers(MTP_vector<MTPUser>(1, dv.vuser), false);
|
||||
MTPint userId(MTP_int(0));
|
||||
switch (dv.vuser.type()) {
|
||||
case mtpc_userEmpty: userId = dv.vuser.c_userEmpty().vid; break;
|
||||
case mtpc_user: userId = dv.vuser.c_user().vid; break;
|
||||
}
|
||||
if (userId.v) {
|
||||
feedUserLink(userId, dv.vmy_link, dv.vforeign_link);
|
||||
feedUserLink(userId, dv.vmy_link, dv.vforeign_link, false);
|
||||
}
|
||||
if (user && App::main()) {
|
||||
if (emitPeerUpdated) {
|
||||
App::main()->peerUpdated(user);
|
||||
} else {
|
||||
markPeerUpdated(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) {
|
||||
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink, bool emitPeerUpdated) {
|
||||
UserData *user = userLoaded(userId.v);
|
||||
if (user) {
|
||||
bool wasContact = (user->contact > 0);
|
||||
@@ -808,7 +856,32 @@ namespace App {
|
||||
}
|
||||
}
|
||||
user->setName(textOneLine(user->firstName), textOneLine(user->lastName), (user->contact || isServiceUser(user->id) || user->phone.isEmpty()) ? QString() : App::formatPhone(user->phone), textOneLine(user->username));
|
||||
if (App::main()) App::main()->peerUpdated(user);
|
||||
if (App::main()) {
|
||||
if (emitPeerUpdated) {
|
||||
App::main()->peerUpdated(user);
|
||||
} else {
|
||||
markPeerUpdated(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void markPeerUpdated(PeerData *data) {
|
||||
updatedPeers.insert(data, true);
|
||||
}
|
||||
|
||||
void clearPeerUpdated(PeerData *data) {
|
||||
updatedPeers.remove(data);
|
||||
}
|
||||
|
||||
void emitPeerUpdated() {
|
||||
if (!updatedPeers.isEmpty() && App::main()) {
|
||||
UpdatedPeers upd = updatedPeers;
|
||||
updatedPeers.clear();
|
||||
|
||||
for (UpdatedPeers::const_iterator i = upd.cbegin(), e = upd.cend(); i != e; ++i) {
|
||||
App::main()->peerUpdated(i.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1222,7 +1295,7 @@ namespace App {
|
||||
}
|
||||
convert->id = document;
|
||||
convert->status = FileReady;
|
||||
sentSticker = !!convert->sticker;
|
||||
sentSticker = !!convert->sticker();
|
||||
}
|
||||
convert->access = access;
|
||||
if (!convert->date && date) {
|
||||
@@ -1236,20 +1309,20 @@ namespace App {
|
||||
if (!thumb->isNull() && (convert->thumb->isNull() || convert->thumb->width() < thumb->width() || convert->thumb->height() < thumb->height())) {
|
||||
convert->thumb = thumb;
|
||||
}
|
||||
if (convert->sticker && !attributes.isEmpty() && (convert->sticker->alt.isEmpty() || convert->sticker->set.type() == mtpc_inputStickerSetEmpty)) {
|
||||
if (convert->sticker() && !attributes.isEmpty() && (convert->sticker()->alt.isEmpty() || convert->sticker()->set.type() == mtpc_inputStickerSetEmpty)) {
|
||||
for (QVector<MTPDocumentAttribute>::const_iterator i = attributes.cbegin(), e = attributes.cend(); i != e; ++i) {
|
||||
if (i->type() == mtpc_documentAttributeSticker) {
|
||||
const MTPDdocumentAttributeSticker &d(i->c_documentAttributeSticker());
|
||||
if (d.valt.c_string().v.length() > 0) {
|
||||
convert->sticker->alt = qs(d.valt);
|
||||
convert->sticker->set = d.vstickerset;
|
||||
convert->sticker()->alt = qs(d.valt);
|
||||
convert->sticker()->set = d.vstickerset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (convert->sticker && !convert->sticker->loc.dc && thumbLocation.dc) {
|
||||
convert->sticker->loc = thumbLocation;
|
||||
if (convert->sticker() && !convert->sticker()->loc.dc && thumbLocation.dc) {
|
||||
convert->sticker()->loc = thumbLocation;
|
||||
}
|
||||
|
||||
if (convert->location.check()) {
|
||||
@@ -1263,7 +1336,7 @@ namespace App {
|
||||
result = convert;
|
||||
} else {
|
||||
result = new DocumentData(document, access, date, attributes, mime, thumb, dc, size);
|
||||
if (result->sticker) result->sticker->loc = thumbLocation;
|
||||
if (result->sticker()) result->sticker()->loc = thumbLocation;
|
||||
}
|
||||
documentsData.insert(document, result);
|
||||
} else {
|
||||
@@ -1281,19 +1354,19 @@ namespace App {
|
||||
if (!thumb->isNull() && (result->thumb->isNull() || result->thumb->width() < thumb->width() || result->thumb->height() < thumb->height())) {
|
||||
result->thumb = thumb;
|
||||
}
|
||||
if (result->sticker && !attributes.isEmpty() && (result->sticker->alt.isEmpty() || result->sticker->set.type() == mtpc_inputStickerSetEmpty)) {
|
||||
if (result->sticker() && !attributes.isEmpty() && (result->sticker()->alt.isEmpty() || result->sticker()->set.type() == mtpc_inputStickerSetEmpty)) {
|
||||
for (QVector<MTPDocumentAttribute>::const_iterator i = attributes.cbegin(), e = attributes.cend(); i != e; ++i) {
|
||||
if (i->type() == mtpc_documentAttributeSticker) {
|
||||
const MTPDdocumentAttributeSticker &d(i->c_documentAttributeSticker());
|
||||
if (d.valt.c_string().v.length() > 0) {
|
||||
result->sticker->alt = qs(d.valt);
|
||||
result->sticker->set = d.vstickerset;
|
||||
result->sticker()->alt = qs(d.valt);
|
||||
result->sticker()->set = d.vstickerset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result->sticker && !result->sticker->loc.dc && thumbLocation.dc) {
|
||||
result->sticker->loc = thumbLocation;
|
||||
if (result->sticker() && !result->sticker()->loc.dc && thumbLocation.dc) {
|
||||
result->sticker()->loc = thumbLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1546,6 +1619,7 @@ namespace App {
|
||||
historyClearMsgs();
|
||||
randomData.clear();
|
||||
mutedPeers.clear();
|
||||
updatedPeers.clear();
|
||||
for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) {
|
||||
delete *i;
|
||||
}
|
||||
@@ -1573,7 +1647,6 @@ namespace App {
|
||||
if (api()) api()->clearWebPageRequests();
|
||||
cSetRecentStickers(RecentStickerPack());
|
||||
cSetStickersHash(QByteArray());
|
||||
cSetEmojiStickers(EmojiStickersMap());
|
||||
cSetStickerSets(StickerSets());
|
||||
cSetStickerSetsOrder(StickerSetsOrder());
|
||||
cSetLastStickersUpdate(0);
|
||||
|
||||
@@ -105,20 +105,25 @@ namespace App {
|
||||
int32 onlineForSort(UserData *user, int32 now);
|
||||
int32 onlineWillChangeIn(UserData *user, int32 nowOnServer);
|
||||
QString onlineText(UserData *user, int32 nowOnServer, bool precise = false);
|
||||
bool onlineColorUse(int32 online, int32 now);
|
||||
bool onlineColorUse(UserData *user, int32 now);
|
||||
|
||||
UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user
|
||||
ChatData *feedChats(const MTPVector<MTPChat> &chats); // returns last chat
|
||||
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos = false);
|
||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
|
||||
UserData *feedUsers(const MTPVector<MTPUser> &users, bool emitPeerUpdated = true); // returns last user
|
||||
ChatData *feedChats(const MTPVector<MTPChat> &chats, bool emitPeerUpdated = true); // returns last chat
|
||||
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos, bool emitPeerUpdated = true);
|
||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated = true);
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated = true);
|
||||
void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState = 0); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message
|
||||
void feedWereRead(const QVector<MTPint> &msgsIds);
|
||||
void feedInboxRead(const PeerId &peer, int32 upTo);
|
||||
void feedOutboxRead(const PeerId &peer, int32 upTo);
|
||||
void feedWereDeleted(const QVector<MTPint> &msgsIds);
|
||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links);
|
||||
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink);
|
||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links, bool emitPeerUpdated = true);
|
||||
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink, bool emitPeerUpdated = true);
|
||||
|
||||
void markPeerUpdated(PeerData *data);
|
||||
void clearPeerUpdated(PeerData *data);
|
||||
void emitPeerUpdated();
|
||||
|
||||
int32 maxMsgId();
|
||||
|
||||
ImagePtr image(const MTPPhotoSize &size);
|
||||
|
||||
@@ -48,28 +48,43 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
class EventFilterForMac : public QObject {
|
||||
class EventFilterForKeys : public QObject {
|
||||
public:
|
||||
|
||||
EventFilterForMac(QObject *parent) : QObject(parent) {
|
||||
EventFilterForKeys(QObject *parent) : QObject(parent) {
|
||||
|
||||
}
|
||||
bool eventFilter(QObject *o, QEvent *e) {
|
||||
if (e->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
|
||||
if (ev->key() == Qt::Key_W && (ev->modifiers() & (Qt::MetaModifier | Qt::ControlModifier))) {
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
App::wnd()->minimizeToTray();
|
||||
return true;
|
||||
} else {
|
||||
App::wnd()->hide();
|
||||
App::wnd()->updateIsActive(cOfflineBlurTimeout());
|
||||
App::wnd()->updateGlobalMenu();
|
||||
if (cPlatform() == dbipMac) {
|
||||
if (ev->key() == Qt::Key_W && (ev->modifiers() & (Qt::MetaModifier | Qt::ControlModifier))) {
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
App::wnd()->minimizeToTray();
|
||||
return true;
|
||||
} else {
|
||||
App::wnd()->hide();
|
||||
App::wnd()->updateIsActive(cOfflineBlurTimeout());
|
||||
App::wnd()->updateGlobalMenu();
|
||||
return true;
|
||||
}
|
||||
} else if (ev->key() == Qt::Key_M && (ev->modifiers() & (Qt::MetaModifier | Qt::ControlModifier))) {
|
||||
App::wnd()->setWindowState(Qt::WindowMinimized);
|
||||
return true;
|
||||
}
|
||||
} else if (ev->key() == Qt::Key_M && (ev->modifiers() & (Qt::MetaModifier | Qt::ControlModifier))) {
|
||||
App::wnd()->setWindowState(Qt::WindowMinimized);
|
||||
return true;
|
||||
}
|
||||
if (ev->key() == Qt::Key_MediaPlay) {
|
||||
if (App::main()) App::main()->player()->playPressed();
|
||||
} else if (ev->key() == Qt::Key_MediaPause) {
|
||||
if (App::main()) App::main()->player()->pausePressed();
|
||||
} else if (ev->key() == Qt::Key_MediaTogglePlayPause) {
|
||||
if (App::main()) App::main()->player()->playPausePressed();
|
||||
} else if (ev->key() == Qt::Key_MediaStop) {
|
||||
if (App::main()) App::main()->player()->stopPressed();
|
||||
} else if (ev->key() == Qt::Key_MediaPrevious) {
|
||||
if (App::main()) App::main()->player()->prevPressed();
|
||||
} else if (ev->key() == Qt::Key_MediaNext) {
|
||||
if (App::main()) App::main()->player()->nextPressed();
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(o, e);
|
||||
@@ -95,9 +110,8 @@ Application::Application(int &argc, char **argv) : PsApplication(argc, argv),
|
||||
}
|
||||
mainApp = this;
|
||||
|
||||
if (cPlatform() == dbipMac) {
|
||||
installEventFilter(new EventFilterForMac(this));
|
||||
}
|
||||
|
||||
installEventFilter(new EventFilterForKeys(this));
|
||||
|
||||
QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/OpenSans-Regular.ttf"));
|
||||
QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/OpenSans-Bold.ttf"));
|
||||
@@ -640,10 +654,10 @@ void Application::checkMapVersion() {
|
||||
psRegisterCustomScheme();
|
||||
if (Local::oldMapVersion()) {
|
||||
QString versionFeatures;
|
||||
if (DevChannel && Local::oldMapVersion() < 8029) {
|
||||
versionFeatures = lang(lng_new_version_minor);// QString::fromUtf8("\xe2\x80\x94 IPv6 connections support\n\xe2\x80\x94 Bug fixes and minor stuff");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
} else if (!DevChannel && Local::oldMapVersion() < 8024) {
|
||||
versionFeatures = lng_new_version_text(lt_blog_link, qsl("https://telegram.org/blog/bot-revolution"));// lang(lng_new_version_text).trimmed();
|
||||
if (DevChannel && Local::oldMapVersion() < 8039) {
|
||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Moved to Qt 5.5\n\xe2\x80\x94 Some bugfixes and optimizations\n\xe2\x80\x94 In OS X 10.10.3 location marks sent from mobile should be displayed now");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
} else if (!DevChannel && Local::oldMapVersion() < 8038) {
|
||||
versionFeatures = lang(lng_new_version_text).trimmed();
|
||||
}
|
||||
if (!versionFeatures.isEmpty()) {
|
||||
versionFeatures = lng_new_version_wrap(lt_version, QString::fromStdWString(AppVersionStr), lt_changes, versionFeatures, lt_link, qsl("https://desktop.telegram.org/#changelog"));
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 167 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 219 KiB After Width: | Height: | Size: 220 KiB |
File diff suppressed because it is too large
Load Diff
@@ -25,14 +25,19 @@ void audioPlayNotify();
|
||||
void audioFinish();
|
||||
|
||||
enum AudioPlayerState {
|
||||
AudioPlayerStopped,
|
||||
AudioPlayerStoppedAtStart,
|
||||
AudioPlayerStarting,
|
||||
AudioPlayerPlaying,
|
||||
AudioPlayerFinishing,
|
||||
AudioPlayerPausing,
|
||||
AudioPlayerPaused,
|
||||
AudioPlayerResuming,
|
||||
AudioPlayerStopped = 0x01,
|
||||
AudioPlayerStoppedAtEnd = 0x02,
|
||||
AudioPlayerStoppedAtError = 0x03,
|
||||
AudioPlayerStoppedAtStart = 0x04,
|
||||
AudioPlayerStoppedMask = 0x07,
|
||||
|
||||
AudioPlayerStarting = 0x08,
|
||||
AudioPlayerPlaying = 0x10,
|
||||
AudioPlayerFinishing = 0x18,
|
||||
AudioPlayerPausing = 0x20,
|
||||
AudioPlayerPaused = 0x28,
|
||||
AudioPlayerPausedAtEnd = 0x30,
|
||||
AudioPlayerResuming = 0x38,
|
||||
};
|
||||
|
||||
class AudioPlayerFader;
|
||||
@@ -45,39 +50,68 @@ public:
|
||||
|
||||
AudioPlayer();
|
||||
|
||||
void play(AudioData *audio);
|
||||
void pauseresume();
|
||||
void play(const AudioMsgId &audio, int64 position = 0);
|
||||
void play(const SongMsgId &song, int64 position = 0);
|
||||
void pauseresume(MediaOverviewType type, bool fast = false);
|
||||
void seek(int64 position); // type == OverviewDocuments
|
||||
void stop(MediaOverviewType type);
|
||||
|
||||
void currentState(AudioMsgId *audio, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0);
|
||||
void currentState(SongMsgId *song, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0);
|
||||
|
||||
void clearStoppedAtStart(const AudioMsgId &audio);
|
||||
void clearStoppedAtStart(const SongMsgId &song);
|
||||
|
||||
void currentState(AudioData **audio, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0);
|
||||
void clearStoppedAtStart(AudioData *audio);
|
||||
void resumeDevice();
|
||||
|
||||
~AudioPlayer();
|
||||
|
||||
public slots:
|
||||
|
||||
void onError(AudioData *audio);
|
||||
void onError(const AudioMsgId &audio);
|
||||
void onError(const SongMsgId &song);
|
||||
|
||||
void onStopped(const AudioMsgId &audio);
|
||||
void onStopped(const SongMsgId &song);
|
||||
|
||||
signals:
|
||||
|
||||
void updated(AudioData *audio);
|
||||
void stopped(AudioData *audio);
|
||||
void updated(const AudioMsgId &audio);
|
||||
void updated(const SongMsgId &song);
|
||||
|
||||
void stopped(const AudioMsgId &audio);
|
||||
void stopped(const SongMsgId &song);
|
||||
|
||||
void stoppedOnError(const AudioMsgId &audio);
|
||||
void stoppedOnError(const SongMsgId &song);
|
||||
|
||||
void loaderOnStart(const AudioMsgId &audio, qint64 position);
|
||||
void loaderOnStart(const SongMsgId &song, qint64 position);
|
||||
|
||||
void loaderOnCancel(const AudioMsgId &audio);
|
||||
void loaderOnCancel(const SongMsgId &song);
|
||||
|
||||
void faderOnTimer();
|
||||
void loaderOnStart(AudioData *audio);
|
||||
void loaderOnCancel(AudioData *audio);
|
||||
|
||||
void suppressSong();
|
||||
void unsuppressSong();
|
||||
void suppressAll();
|
||||
|
||||
void songVolumeChanged();
|
||||
|
||||
private:
|
||||
|
||||
bool updateCurrentStarted(int32 pos = -1);
|
||||
bool fadedStop(MediaOverviewType type, bool *fadedStart = 0);
|
||||
bool updateCurrentStarted(MediaOverviewType type, int32 pos = -1);
|
||||
bool checkCurrentALError(MediaOverviewType type);
|
||||
|
||||
struct Msg {
|
||||
Msg() : audio(0), position(0), duration(0), frequency(AudioVoiceMsgFrequency), skipStart(0), skipEnd(0), loading(0), started(0),
|
||||
Msg() : position(0), duration(0), frequency(AudioVoiceMsgFrequency), skipStart(0), skipEnd(0), loading(0), started(0),
|
||||
state(AudioPlayerStopped), source(0), nextBuffer(0) {
|
||||
memset(buffers, 0, sizeof(buffers));
|
||||
memset(samplesCount, 0, sizeof(samplesCount));
|
||||
}
|
||||
AudioData *audio;
|
||||
|
||||
QString fname;
|
||||
QByteArray data;
|
||||
int64 position, duration;
|
||||
@@ -92,9 +126,25 @@ private:
|
||||
uint32 buffers[3];
|
||||
int64 samplesCount[3];
|
||||
};
|
||||
struct AudioMsg : public Msg {
|
||||
AudioMsg() {
|
||||
}
|
||||
AudioMsgId audio;
|
||||
};
|
||||
struct SongMsg : public Msg {
|
||||
SongMsg() {
|
||||
}
|
||||
SongMsgId song;
|
||||
};
|
||||
|
||||
int32 _current;
|
||||
Msg _data[AudioVoiceMsgSimultaneously];
|
||||
void currentState(Msg *current, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency);
|
||||
void setStoppedState(Msg *current, AudioPlayerState state = AudioPlayerStopped);
|
||||
|
||||
int32 _audioCurrent;
|
||||
AudioMsg _audioData[AudioVoiceMsgSimultaneously];
|
||||
|
||||
int32 _songCurrent;
|
||||
SongMsg _songData[AudioSongSimultaneously];
|
||||
|
||||
QMutex _mutex;
|
||||
|
||||
@@ -154,10 +204,14 @@ public:
|
||||
|
||||
signals:
|
||||
|
||||
void error(AudioData *audio);
|
||||
void playPositionUpdated(AudioData *audio);
|
||||
void audioStopped(AudioData *audio);
|
||||
void needToPreload(AudioData *audio);
|
||||
void error(const AudioMsgId &audio);
|
||||
void error(const SongMsgId &audio);
|
||||
void playPositionUpdated(const AudioMsgId &audio);
|
||||
void playPositionUpdated(const SongMsgId &audio);
|
||||
void audioStopped(const AudioMsgId &audio);
|
||||
void audioStopped(const SongMsgId &audio);
|
||||
void needToPreload(const AudioMsgId &audio);
|
||||
void needToPreload(const SongMsgId &audio);
|
||||
|
||||
void stopPauseDevice();
|
||||
|
||||
@@ -168,12 +222,30 @@ public slots:
|
||||
void onPauseTimer();
|
||||
void onPauseTimerStop();
|
||||
|
||||
void onSuppressSong();
|
||||
void onUnsuppressSong();
|
||||
void onSuppressAll();
|
||||
void onSongVolumeChanged();
|
||||
|
||||
private:
|
||||
|
||||
enum {
|
||||
EmitError = 0x01,
|
||||
EmitStopped = 0x02,
|
||||
EmitPositionUpdated = 0x04,
|
||||
EmitNeedToPreload = 0x08,
|
||||
};
|
||||
int32 updateOnePlayback(AudioPlayer::Msg *m, bool &hasPlaying, bool &hasFading, float64 suppressGain, bool suppressGainChanged);
|
||||
void setStoppedState(AudioPlayer::Msg *m, AudioPlayerState state = AudioPlayerStopped);
|
||||
|
||||
QTimer _timer, _pauseTimer;
|
||||
QMutex _pauseMutex;
|
||||
bool _pauseFlag, _paused;
|
||||
|
||||
bool _suppressAll, _suppressAllAnim, _suppressSong, _suppressSongAnim, _songVolumeChanged;
|
||||
anim::fvalue _suppressAllGain, _suppressSongGain;
|
||||
uint64 _suppressAllStart, _suppressSongStart;
|
||||
|
||||
};
|
||||
|
||||
class AudioPlayerLoader;
|
||||
@@ -187,22 +259,46 @@ public:
|
||||
|
||||
signals:
|
||||
|
||||
void error(AudioData *audio);
|
||||
void error(const AudioMsgId &audio);
|
||||
void error(const SongMsgId &song);
|
||||
void needToCheck();
|
||||
|
||||
public slots:
|
||||
|
||||
void onInit();
|
||||
void onStart(AudioData *audio);
|
||||
void onLoad(AudioData *audio);
|
||||
void onCancel(AudioData *audio);
|
||||
|
||||
|
||||
void onStart(const AudioMsgId &audio, qint64 position);
|
||||
void onStart(const SongMsgId &audio, qint64 position);
|
||||
|
||||
void onLoad(const AudioMsgId &audio);
|
||||
void onLoad(const SongMsgId &audio);
|
||||
|
||||
void onCancel(const AudioMsgId &audio);
|
||||
void onCancel(const SongMsgId &audio);
|
||||
|
||||
private:
|
||||
|
||||
typedef QMap<AudioData*, AudioPlayerLoader*> Loaders;
|
||||
Loaders _loaders;
|
||||
AudioMsgId _audio;
|
||||
AudioPlayerLoader *_audioLoader;
|
||||
|
||||
void loadError(Loaders::iterator i);
|
||||
SongMsgId _song;
|
||||
AudioPlayerLoader *_songLoader;
|
||||
|
||||
void emitError(MediaOverviewType type);
|
||||
void clear(MediaOverviewType type);
|
||||
void setStoppedState(AudioPlayer::Msg *m, AudioPlayerState state = AudioPlayerStopped);
|
||||
AudioMsgId clearAudio();
|
||||
SongMsgId clearSong();
|
||||
|
||||
enum SetupError {
|
||||
SetupErrorAtStart = 0,
|
||||
SetupErrorNotPlaying = 1,
|
||||
SetupErrorLoadedFull = 2,
|
||||
SetupNoErrorStarted = 3,
|
||||
};
|
||||
void loadData(MediaOverviewType type, const void *objId, qint64 position);
|
||||
AudioPlayerLoader *setupLoader(MediaOverviewType type, const void *objId, SetupError &err, qint64 position);
|
||||
AudioPlayer::Msg *checkLoader(MediaOverviewType type);
|
||||
|
||||
};
|
||||
|
||||
@@ -239,3 +335,5 @@ private:
|
||||
QByteArray _captured;
|
||||
|
||||
};
|
||||
|
||||
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat);
|
||||
|
||||
@@ -33,7 +33,8 @@ ConnectionBox::ConnectionBox() :
|
||||
_passwordInput(this, st::inpConnectionPassword, lang(lng_connection_password_ph), cConnectionProxy().password),
|
||||
_autoRadio(this, qsl("conn_type"), dbictAuto, lang(lng_connection_auto_rb), (cConnectionType() == dbictAuto)),
|
||||
_httpProxyRadio(this, qsl("conn_type"), dbictHttpProxy, lang(lng_connection_http_proxy_rb), (cConnectionType() == dbictHttpProxy)),
|
||||
_tcpProxyRadio(this, qsl("conn_type"), dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), (cConnectionType() == dbictTcpProxy)) {
|
||||
_tcpProxyRadio(this, qsl("conn_type"), dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), (cConnectionType() == dbictTcpProxy)),
|
||||
_tryIPv6(this, lang(lng_connection_try_ipv6), cTryIPv6()) {
|
||||
|
||||
connect(&_saveButton, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||
connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
@@ -51,6 +52,7 @@ void ConnectionBox::hideAll() {
|
||||
_autoRadio.hide();
|
||||
_httpProxyRadio.hide();
|
||||
_tcpProxyRadio.hide();
|
||||
_tryIPv6.hide();
|
||||
|
||||
_hostInput.hide();
|
||||
_portInput.hide();
|
||||
@@ -65,8 +67,9 @@ void ConnectionBox::showAll() {
|
||||
_autoRadio.show();
|
||||
_httpProxyRadio.show();
|
||||
_tcpProxyRadio.show();
|
||||
_tryIPv6.show();
|
||||
|
||||
int32 h = st::boxTitleHeight + st::connectionSkip + _autoRadio.height() + st::connectionSkip + _httpProxyRadio.height() + st::connectionSkip + _tcpProxyRadio.height() + st::connectionSkip;
|
||||
int32 h = st::boxTitleHeight + st::connectionSkip + _autoRadio.height() + st::connectionSkip + _httpProxyRadio.height() + st::connectionSkip + _tcpProxyRadio.height() + st::connectionSkip + st::lineWidth + st::connectionSkip + _tryIPv6.height() + st::connectionSkip;
|
||||
if (_httpProxyRadio.checked() || _tcpProxyRadio.checked()) {
|
||||
h += 2 * st::boxPadding.top() + 2 * _hostInput.height();
|
||||
_hostInput.show();
|
||||
@@ -99,6 +102,9 @@ void ConnectionBox::paintEvent(QPaintEvent *e) {
|
||||
|
||||
paintTitle(p, lang(lng_connection_header), true);
|
||||
|
||||
// paint separator
|
||||
p.fillRect(st::boxPadding.left(), _tryIPv6.y() - st::connectionSkip - st::lineWidth, width() - st::boxPadding.left() - st::boxPadding.right(), st::lineWidth, st::scrollDef.shColor->b);
|
||||
|
||||
// paint shadow
|
||||
p.fillRect(0, height() - st::btnSelectCancel.height - st::scrollDef.bottomsh, width(), st::scrollDef.bottomsh, st::scrollDef.shColor->b);
|
||||
|
||||
@@ -128,10 +134,11 @@ void ConnectionBox::resizeEvent(QResizeEvent *e) {
|
||||
_passwordInput.move(width() - st::boxPadding.right() - _passwordInput.width(), _userInput.y());
|
||||
}
|
||||
|
||||
int32 buttony = (_tcpProxyRadio.checked() ? (_userInput.y() + _userInput.height()) : (_tcpProxyRadio.y() + _tcpProxyRadio.height())) + st::connectionSkip;
|
||||
int32 tryipv6y = (_tcpProxyRadio.checked() ? (_userInput.y() + _userInput.height()) : (_tcpProxyRadio.y() + _tcpProxyRadio.height())) + st::connectionSkip + st::lineWidth + st::connectionSkip;
|
||||
_tryIPv6.move(st::boxPadding.left(), tryipv6y);
|
||||
|
||||
_saveButton.move(width() - _saveButton.width(), buttony);
|
||||
_cancelButton.move(0, buttony);
|
||||
_saveButton.move(width() - _saveButton.width(), _tryIPv6.y() + _tryIPv6.height() + st::connectionSkip);
|
||||
_cancelButton.move(0, _saveButton.y());
|
||||
}
|
||||
|
||||
void ConnectionBox::onChange() {
|
||||
@@ -172,8 +179,17 @@ void ConnectionBox::onSave() {
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
}
|
||||
Local::writeSettings();
|
||||
MTP::restart();
|
||||
reinitImageLinkManager();
|
||||
emit closed();
|
||||
if (cPlatform() == dbipWindows && cTryIPv6() != _tryIPv6.checked()) {
|
||||
cSetTryIPv6(_tryIPv6.checked());
|
||||
Local::writeSettings();
|
||||
cSetRestarting(true);
|
||||
cSetRestartingToSettings(true);
|
||||
App::quit();
|
||||
} else {
|
||||
cSetTryIPv6(_tryIPv6.checked());
|
||||
Local::writeSettings();
|
||||
MTP::restart();
|
||||
reinitImageLinkManager();
|
||||
emit closed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,4 +47,5 @@ private:
|
||||
PortInput _portInput;
|
||||
FlatInput _userInput, _passwordInput;
|
||||
FlatRadiobutton _autoRadio, _httpProxyRadio, _tcpProxyRadio;
|
||||
FlatCheckbox _tryIPv6;
|
||||
};
|
||||
|
||||
@@ -249,7 +249,7 @@ void ContactsInner::paintDialog(QPainter &p, PeerData *peer, ContactData *data,
|
||||
} else {
|
||||
if (data->inchat || data->check) {
|
||||
p.setPen(st::white->p);
|
||||
} else if (user && (uname || App::onlineColorUse(user->onlineTill, _time))) {
|
||||
} else if (user && (uname || App::onlineColorUse(user, _time))) {
|
||||
p.setPen(st::profileOnlineColor->p);
|
||||
} else {
|
||||
p.setPen(st::profileOfflineColor->p);
|
||||
|
||||
@@ -264,12 +264,12 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) {
|
||||
|
||||
QString appName, appVer = qs(d.vapp_version), systemVer = qs(d.vsystem_version), deviceModel = qs(d.vdevice_model);
|
||||
if (d.vapi_id.v == 2040 || d.vapi_id.v == 17349) {
|
||||
appName = (d.vapi_id.v == 2040) ? qsl("Telegram Desktop") : qsl("Telegram Desktop (GitHub)");
|
||||
// if (systemVer == QLatin1String("windows")) {
|
||||
appName = (d.vapi_id.v == 2040) ? qstr("Telegram Desktop") : qstr("Telegram Desktop (GitHub)");
|
||||
// if (systemVer == qstr("windows")) {
|
||||
// deviceModel = qsl("Windows");
|
||||
// } else if (systemVer == QLatin1String("os x")) {
|
||||
// } else if (systemVer == qstr("os x")) {
|
||||
// deviceModel = qsl("OS X");
|
||||
// } else if (systemVer == QLatin1String("linux")) {
|
||||
// } else if (systemVer == qstr("linux")) {
|
||||
// deviceModel = qsl("Linux");
|
||||
// }
|
||||
if (appVer == QString::number(appVer.toInt())) {
|
||||
@@ -293,7 +293,7 @@ void SessionsBox::gotAuthorizations(const MTPaccount_Authorizations &result) {
|
||||
MTPint active = d.vdate_active.v ? d.vdate_active : d.vdate_created;
|
||||
data.activeTime = active.v;
|
||||
|
||||
data.info = qs(d.vdevice_model) + QLatin1String(", ") + (platform.isEmpty() ? QString() : platform + ' ') + qs(d.vsystem_version);
|
||||
data.info = qs(d.vdevice_model) + qstr(", ") + (platform.isEmpty() ? QString() : platform + ' ') + qs(d.vsystem_version);
|
||||
data.ip = qs(d.vip) + (country.isEmpty() ? QString() : QString::fromUtf8(" \xe2\x80\x93 ") + country);
|
||||
if (!data.hash || (d.vflags.v & 1)) {
|
||||
data.active = QString();
|
||||
|
||||
@@ -27,7 +27,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include "localstorage.h"
|
||||
|
||||
StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) :
|
||||
_loaded(false), _setId(0), _setAccess(0), _bottom(0),
|
||||
_loaded(false), _setId(0), _setAccess(0), _setCount(0), _setHash(0), _setFlags(0), _bottom(0),
|
||||
_input(set), _installRequest(0) {
|
||||
switch (set.type()) {
|
||||
case mtpc_inputStickerSetID: _setId = set.c_inputStickerSetID().vid.v; _setAccess = set.c_inputStickerSetID().vaccess_hash.v; break;
|
||||
@@ -46,7 +46,7 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||
_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;
|
||||
if (!doc || !doc->sticker()) continue;
|
||||
|
||||
_pack.push_back(doc);
|
||||
}
|
||||
@@ -57,6 +57,9 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||
_setShortName = qs(s.vshort_name);
|
||||
_setId = s.vid.v;
|
||||
_setAccess = s.vaccess_hash.v;
|
||||
_setCount = s.vcount.v;
|
||||
_setHash = s.vhash.v;
|
||||
_setFlags = s.vflags.v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,13 +87,25 @@ bool StickerSetInner::failedSet(const RPCError &error) {
|
||||
void StickerSetInner::installDone(const MTPBool &result) {
|
||||
StickerSets &sets(cRefStickerSets());
|
||||
|
||||
sets.insert(_setId, StickerSet(_setId, _setAccess, _setTitle, _setShortName)).value().stickers = _pack;
|
||||
int32 index = cStickerSetsOrder().indexOf(_setId);
|
||||
if (index > 0) {
|
||||
cRefStickerSetsOrder().removeAt(index);
|
||||
cRefStickerSetsOrder().push_front(_setId);
|
||||
} else if (index < 0) {
|
||||
cRefStickerSetsOrder().push_front(_setId);
|
||||
sets.insert(_setId, StickerSet(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)).value().stickers = _pack;
|
||||
|
||||
int32 insertAtIndex = 0;
|
||||
StickerSetsOrder &order(cRefStickerSetsOrder());
|
||||
for (int32 s = order.size(); insertAtIndex < s; ++insertAtIndex) {
|
||||
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 > 0) {
|
||||
order.removeAt(currentIndex);
|
||||
if (currentIndex < insertAtIndex) {
|
||||
--insertAtIndex;
|
||||
}
|
||||
}
|
||||
order.insert(insertAtIndex, _setId);
|
||||
}
|
||||
|
||||
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
||||
@@ -141,11 +156,11 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
|
||||
if (!doc->loader && doc->status != FileFailed && !already && !hasdata) {
|
||||
doc->save(QString());
|
||||
}
|
||||
if (doc->sticker->img->isNull() && (already || hasdata)) {
|
||||
if (doc->sticker()->img->isNull() && (already || hasdata)) {
|
||||
if (already) {
|
||||
doc->sticker->img = ImagePtr(doc->already());
|
||||
doc->sticker()->img = ImagePtr(doc->already());
|
||||
} else {
|
||||
doc->sticker->img = ImagePtr(doc->data);
|
||||
doc->sticker()->img = ImagePtr(doc->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,8 +173,8 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
|
||||
QPoint ppos = pos + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2);
|
||||
if (goodThumb) {
|
||||
p.drawPixmapLeft(ppos, width(), doc->thumb->pix(w, h));
|
||||
} else if (!doc->sticker->img->isNull()) {
|
||||
p.drawPixmapLeft(ppos, width(), doc->sticker->img->pix(w, h));
|
||||
} else if (!doc->sticker()->img->isNull()) {
|
||||
p.drawPixmapLeft(ppos, width(), doc->sticker()->img->pix(w, h));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,7 +208,7 @@ QString StickerSetInner::shortName() const {
|
||||
|
||||
void StickerSetInner::install() {
|
||||
if (_installRequest) return;
|
||||
_installRequest = MTP::send(MTPmessages_InstallStickerSet(_input), rpcDone(&StickerSetInner::installDone), rpcFail(&StickerSetInner::installFailed));
|
||||
_installRequest = MTP::send(MTPmessages_InstallStickerSet(_input, MTP_bool(false)), rpcDone(&StickerSetInner::installDone), rpcFail(&StickerSetInner::installFailed));
|
||||
}
|
||||
|
||||
StickerSetInner::~StickerSetInner() {
|
||||
@@ -235,7 +250,6 @@ void StickerSetBox::onAddStickers() {
|
||||
|
||||
void StickerSetBox::onShareStickers() {
|
||||
QString url = qsl("https://telegram.me/addstickers/") + _inner.shortName();
|
||||
DEBUG_LOG(("Setting text to clipboard from stickerset box: %1").arg(url));
|
||||
QApplication::clipboard()->setText(url);
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_stickers_copied), true), true);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ private:
|
||||
bool _loaded;
|
||||
uint64 _setId, _setAccess;
|
||||
QString _title, _setTitle, _setShortName;
|
||||
int32 _setCount, _setHash, _setFlags;
|
||||
|
||||
int32 _bottom;
|
||||
MTPInputStickerSet _input;
|
||||
|
||||
@@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
static const int32 AppVersion = 8029;
|
||||
static const wchar_t *AppVersionStr = L"0.8.29";
|
||||
static const int32 AppVersion = 8039;
|
||||
static const wchar_t *AppVersionStr = L"0.8.39";
|
||||
static const bool DevChannel = true;
|
||||
|
||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||
@@ -85,9 +85,10 @@ enum {
|
||||
MediaOverviewPreloadCount = 4,
|
||||
|
||||
AudioVoiceMsgSimultaneously = 4,
|
||||
AudioSongSimultaneously = 4,
|
||||
AudioCheckPositionTimeout = 100, // 100ms per check audio pos
|
||||
AudioCheckPositionDelta = 4800, // update position called each 4800 samples
|
||||
AudioFadeTimeout = 10, // 10ms
|
||||
AudioCheckPositionDelta = 2400, // update position called each 2400 samples
|
||||
AudioFadeTimeout = 7, // 7ms
|
||||
AudioFadeDuration = 500,
|
||||
AudioVoiceMsgSkip = 400, // 200ms
|
||||
AudioVoiceMsgFade = 300, // 300ms
|
||||
@@ -100,7 +101,7 @@ enum {
|
||||
AudioVoiceMsgInMemory = 1024 * 1024, // 1 Mb audio is hold in memory and auto loaded
|
||||
AudioPauseDeviceTimeout = 3000, // pause in 3 secs after playing is over
|
||||
|
||||
StickerInMemory = 256 * 1024, // 128 Kb stickers hold in memory, auto loaded and displayed inline
|
||||
StickerInMemory = 1024 * 1024, // 1024 Kb stickers hold in memory, auto loaded and displayed inline
|
||||
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
||||
|
||||
MediaViewImageSizeLimit = 100 * 1024 * 1024, // show up to 100mb jpg/png/gif docs in app
|
||||
@@ -139,6 +140,8 @@ enum {
|
||||
|
||||
WrongPasscodeTimeout = 1500,
|
||||
SessionsShortPollTimeout = 60000,
|
||||
|
||||
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
|
||||
};
|
||||
|
||||
inline bool isServiceUser(uint64 id) {
|
||||
|
||||
@@ -680,6 +680,26 @@ void DialogsListWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem)
|
||||
}
|
||||
}
|
||||
|
||||
PeerData *DialogsListWidget::updateFromParentDrag(QPoint globalPos) {
|
||||
lastMousePos = globalPos;
|
||||
selByMouse = true;
|
||||
onUpdateSelected(true);
|
||||
update();
|
||||
|
||||
if (_state == DefaultState) {
|
||||
if (sel) return sel->history->peer;
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (filteredSel >= 0 && filteredSel < filterResults.size()) {
|
||||
return filterResults[filteredSel]->history->peer;
|
||||
} else if (peopleSel >= 0 && peopleSel < peopleResults.size()) {
|
||||
return peopleResults[peopleSel];
|
||||
} else if (searchedSel >= 0 && searchedSel < searchResults.size()) {
|
||||
return searchResults[searchedSel]->_item->history()->peer;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DialogsListWidget::itemRemoved(HistoryItem *item) {
|
||||
int wasCount = searchResults.size();
|
||||
for (int i = 0; i < searchResults.size();) {
|
||||
@@ -1356,6 +1376,8 @@ MsgId DialogsListWidget::lastSearchId() const {
|
||||
|
||||
DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
|
||||
, _drawShadow(true)
|
||||
, _dragInScroll(false)
|
||||
, _dragForward(false)
|
||||
, dlgOffset(0)
|
||||
, dlgCount(-1)
|
||||
, dlgPreloading(0)
|
||||
@@ -1388,6 +1410,11 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
|
||||
connect(&_newGroup, SIGNAL(clicked()), this, SLOT(onNewGroup()));
|
||||
connect(&_cancelSearch, SIGNAL(clicked()), this, SLOT(onCancelSearch()));
|
||||
|
||||
_chooseByDragTimer.setSingleShot(true);
|
||||
connect(&_chooseByDragTimer, SIGNAL(timeout()), this, SLOT(onChooseByDrag()));
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
_searchTimer.setSingleShot(true);
|
||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
||||
|
||||
@@ -1604,6 +1631,10 @@ void DialogsWidget::onNeedSearchMessages() {
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::onChooseByDrag() {
|
||||
list.choosePeer();
|
||||
}
|
||||
|
||||
void DialogsWidget::searchMessages(const QString &query) {
|
||||
if (_filter.text() != query) {
|
||||
_filter.setText(query);
|
||||
@@ -1741,6 +1772,78 @@ bool DialogsWidget::addNewContact(int32 uid, bool show) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) {
|
||||
if (App::main()->selectingPeer()) return;
|
||||
|
||||
_dragInScroll = false;
|
||||
_dragForward = e->mimeData()->hasFormat(qsl("application/x-td-forward-selected"));
|
||||
if (!_dragForward) _dragForward = e->mimeData()->hasFormat(qsl("application/x-td-forward-pressed-link"));
|
||||
if (!_dragForward) _dragForward = e->mimeData()->hasFormat(qsl("application/x-td-forward-pressed"));
|
||||
if (_dragForward && !cWideMode()) _dragForward = false;
|
||||
if (_dragForward) {
|
||||
e->setDropAction(Qt::CopyAction);
|
||||
e->accept();
|
||||
updateDragInScroll(scroll.geometry().contains(e->pos()));
|
||||
} else if (App::main() && App::main()->getDragState(e->mimeData()) != DragStateNone) {
|
||||
e->setDropAction(Qt::CopyAction);
|
||||
e->accept();
|
||||
}
|
||||
_chooseByDragTimer.stop();
|
||||
}
|
||||
|
||||
void DialogsWidget::dragMoveEvent(QDragMoveEvent *e) {
|
||||
if (scroll.geometry().contains(e->pos())) {
|
||||
if (_dragForward) {
|
||||
updateDragInScroll(true);
|
||||
} else {
|
||||
_chooseByDragTimer.start(ChoosePeerByDragTimeout);
|
||||
}
|
||||
PeerData *p = list.updateFromParentDrag(mapToGlobal(e->pos()));
|
||||
if (p) {
|
||||
e->setDropAction(Qt::CopyAction);
|
||||
} else {
|
||||
e->setDropAction(Qt::IgnoreAction);
|
||||
}
|
||||
} else {
|
||||
if (_dragForward) updateDragInScroll(false);
|
||||
list.leaveEvent(0);
|
||||
e->setDropAction(Qt::IgnoreAction);
|
||||
}
|
||||
e->accept();
|
||||
}
|
||||
|
||||
void DialogsWidget::dragLeaveEvent(QDragLeaveEvent *e) {
|
||||
if (_dragForward) {
|
||||
updateDragInScroll(false);
|
||||
} else {
|
||||
_chooseByDragTimer.stop();
|
||||
}
|
||||
list.leaveEvent(0);
|
||||
e->accept();
|
||||
}
|
||||
|
||||
void DialogsWidget::updateDragInScroll(bool inScroll) {
|
||||
if (_dragInScroll != inScroll) {
|
||||
_dragInScroll = inScroll;
|
||||
if (_dragInScroll) {
|
||||
App::main()->forwardLayer(1);
|
||||
} else {
|
||||
App::main()->dialogsCancelled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::dropEvent(QDropEvent *e) {
|
||||
_chooseByDragTimer.stop();
|
||||
if (scroll.geometry().contains(e->pos())) {
|
||||
PeerData *p = list.updateFromParentDrag(mapToGlobal(e->pos()));
|
||||
if (p) {
|
||||
e->acceptProposedAction();
|
||||
App::main()->onFilesOrForwardDrop(p->id, e->mimeData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::onListScroll() {
|
||||
// if (!App::self()) return;
|
||||
|
||||
@@ -1826,9 +1929,16 @@ void DialogsWidget::resizeEvent(QResizeEvent *e) {
|
||||
_addContact.move(w - _addContact.width() - st::dlgPaddingHor, _filter.y());
|
||||
_cancelSearch.move(w - _cancelSearch.width() - st::dlgPaddingHor, _filter.y());
|
||||
scroll.move(0, _filter.height() + 2 * st::dlgFilterPadding);
|
||||
|
||||
int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0;
|
||||
int32 newScrollY = scroll.scrollTop() + addToY;
|
||||
scroll.resize(w, height() - _filter.y() - _filter.height() - st::dlgFilterPadding - st::dlgPaddingVer);
|
||||
list.resize(w, list.height());
|
||||
onListScroll();
|
||||
if (addToY) {
|
||||
scroll.scrollToY(newScrollY);
|
||||
} else {
|
||||
onListScroll();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::keyPressEvent(QKeyEvent *e) {
|
||||
|
||||
@@ -98,6 +98,8 @@ public:
|
||||
void itemRemoved(HistoryItem *item);
|
||||
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
|
||||
|
||||
PeerData *updateFromParentDrag(QPoint globalPos);
|
||||
|
||||
~DialogsListWidget();
|
||||
|
||||
public slots:
|
||||
@@ -171,6 +173,12 @@ public:
|
||||
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
|
||||
bool addNewContact(int32 uid, bool show = true);
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent *e);
|
||||
void dragMoveEvent(QDragMoveEvent *e);
|
||||
void dragLeaveEvent(QDragLeaveEvent *e);
|
||||
void dropEvent(QDropEvent *e);
|
||||
void updateDragInScroll(bool inScroll);
|
||||
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
@@ -228,10 +236,15 @@ public slots:
|
||||
bool onSearchMessages(bool searchCache = false);
|
||||
void onNeedSearchMessages();
|
||||
|
||||
void onChooseByDrag();
|
||||
|
||||
private:
|
||||
|
||||
bool _drawShadow;
|
||||
|
||||
bool _dragInScroll, _dragForward;
|
||||
QTimer _chooseByDragTimer;
|
||||
|
||||
void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
|
||||
bool dialogsFailed(const RPCError &error);
|
||||
bool contactsFailed(const RPCError &error);
|
||||
|
||||
@@ -384,7 +384,7 @@ void DragArea::dragLeaveEvent(QDragLeaveEvent *e) {
|
||||
void DragArea::dropEvent(QDropEvent *e) {
|
||||
static_cast<HistoryWidget*>(parentWidget())->dropEvent(e);
|
||||
if (e->isAccepted()) {
|
||||
emit dropped(e);
|
||||
emit dropped(e->mimeData());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,10 +684,11 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
||||
p.drawPixmapLeft(w.x() + (st::emojiPanSize.width() - (esize / cIntRetinaFactor())) / 2, w.y() + (st::emojiPanSize.height() - (esize / cIntRetinaFactor())) / 2, width(), App::emojisLarge(), QRect(_variants[variant]->x * esize, _variants[variant]->y * esize, esize, esize));
|
||||
}
|
||||
|
||||
EmojiPanInner::EmojiPanInner(QWidget *parent) : TWidget(parent),
|
||||
EmojiPanInner::EmojiPanInner(QWidget *parent) : TWidget(parent), _maxHeight(int(st::emojiPanMaxHeight)),
|
||||
_top(0), _selected(-1), _pressedSel(-1), _pickerSel(-1), _picker(this),
|
||||
_switcherHover(0), _stickersWidth(st::emojiPanHeaderFont->m.width(lang(lng_switch_stickers))) {
|
||||
resize(st::emojiPanFullSize.width(), countHeight());
|
||||
resize(st::emojiPanWidth, countHeight());
|
||||
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
@@ -709,6 +710,11 @@ _switcherHover(0), _stickersWidth(st::emojiPanHeaderFont->m.width(lang(lng_switc
|
||||
connect(&_picker, SIGNAL(hidden()), this, SLOT(onPickerHidden()));
|
||||
}
|
||||
|
||||
void EmojiPanInner::setMaxHeight(int32 h) {
|
||||
_maxHeight = h;
|
||||
resize(st::emojiPanWidth, countHeight());
|
||||
}
|
||||
|
||||
void EmojiPanInner::setScrollTop(int top) {
|
||||
if (top == _top) return;
|
||||
|
||||
@@ -1131,10 +1137,11 @@ void EmojiPanInner::showEmojiPack(DBIEmojiTab packIndex) {
|
||||
update();
|
||||
}
|
||||
|
||||
StickerPanInner::StickerPanInner(QWidget *parent) : TWidget(parent),
|
||||
StickerPanInner::StickerPanInner(QWidget *parent) : TWidget(parent), _maxHeight(st::emojiPanMaxHeight),
|
||||
_top(0), _selected(-1), _pressedSel(-1),
|
||||
_switcherHover(0), _emojiWidth(st::emojiPanHeaderFont->m.width(lang(lng_switch_emoji))) {
|
||||
resize(st::emojiPanFullSize.width(), countHeight());
|
||||
resize(st::emojiPanWidth, countHeight());
|
||||
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
@@ -1143,6 +1150,11 @@ _switcherHover(0), _emojiWidth(st::emojiPanHeaderFont->m.width(lang(lng_switch_e
|
||||
refreshStickers();
|
||||
}
|
||||
|
||||
void StickerPanInner::setMaxHeight(int32 h) {
|
||||
_maxHeight = h;
|
||||
resize(st::emojiPanWidth, countHeight());
|
||||
}
|
||||
|
||||
void StickerPanInner::setScrollTop(int top) {
|
||||
if (top == _top) return;
|
||||
|
||||
@@ -1154,9 +1166,9 @@ void StickerPanInner::setScrollTop(int top) {
|
||||
}
|
||||
|
||||
int StickerPanInner::countHeight() {
|
||||
int result = 0, minLastH = st::emojiPanFullSize.height() - st::rbEmoji.height - st::stickerPanPadding;
|
||||
int result = 0, minLastH = _maxHeight - st::rbEmoji.height - st::stickerPanPadding;
|
||||
for (int i = 0; i < _sets.size(); ++i) {
|
||||
int cnt = _sets.at(i).size(), rows = (cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0);
|
||||
int cnt = _sets.at(i).pack.size(), rows = (cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0);
|
||||
int h = st::emojiPanHeader + rows * st::stickerPanSize.height();
|
||||
if (i == _sets.size() - 1 && h < minLastH) h = minLastH;
|
||||
result += h;
|
||||
@@ -1174,21 +1186,21 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
|
||||
int32 y, tilly = 0;
|
||||
for (int c = 0, l = _sets.size(); c < l; ++c) {
|
||||
y = tilly;
|
||||
int32 size = _sets.at(c).size();
|
||||
int32 size = _sets.at(c).pack.size();
|
||||
int32 rows = (size / StickerPanPerRow) + ((size % StickerPanPerRow) ? 1 : 0);
|
||||
tilly = y + st::emojiPanHeader + (rows * st::stickerPanSize.height());
|
||||
if (r.top() >= tilly) continue;
|
||||
|
||||
bool special = (_setIds[c] == DefaultStickerSetId || _setIds[c] == RecentStickerSetId);
|
||||
bool special = (_sets[c].flags & MTPDstickerSet_flag_official);
|
||||
y += st::emojiPanHeader;
|
||||
|
||||
QString title = _titles[c];
|
||||
QString title = _sets[c].title;
|
||||
if (r.bottom() <= y) {
|
||||
p.setFont(st::emojiPanHeaderFont->f);
|
||||
p.setPen(st::emojiPanHeaderColor->p);
|
||||
p.drawTextLeft(st::emojiPanHeaderLeft, qMax(y - int(st::emojiPanHeader), _top) + st::emojiPanHeaderTop, width(), title);
|
||||
if (!special && y >= _top + 2 * st::emojiPanHeader) {
|
||||
p.setOpacity(st::stickerPanDeleteOpacity + (1 - st::stickerPanDeleteOpacity) * _hovers[c][size]);
|
||||
p.setOpacity(st::stickerPanDeleteOpacity + (1 - st::stickerPanDeleteOpacity) * _sets[c].hovers[size]);
|
||||
p.drawSpriteRight(QPoint(st::emojiPanHeaderLeft, y - (st::emojiPanHeader + st::notifyClose.icon.pxHeight()) / 2), width(), st::notifyClose.icon);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
@@ -1201,10 +1213,10 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
|
||||
int32 index = i * StickerPanPerRow + j;
|
||||
if (index >= size) break;
|
||||
|
||||
float64 hover = _hovers[c][index];
|
||||
float64 hover = _sets[c].hovers[index];
|
||||
|
||||
DocumentData *sticker = _sets[c][index];
|
||||
if (!sticker->sticker) continue;
|
||||
DocumentData *sticker = _sets[c].pack[index];
|
||||
if (!sticker->sticker()) continue;
|
||||
|
||||
QPoint pos(st::stickerPanPadding + j * st::stickerPanSize.width(), y + i * st::stickerPanSize.height());
|
||||
if (hover > 0) {
|
||||
@@ -1223,11 +1235,11 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
|
||||
if (!sticker->loader && sticker->status != FileFailed && !already && !hasdata) {
|
||||
sticker->save(QString());
|
||||
}
|
||||
if (sticker->sticker->img->isNull() && (already || hasdata)) {
|
||||
if (sticker->sticker()->img->isNull() && (already || hasdata)) {
|
||||
if (already) {
|
||||
sticker->sticker->img = ImagePtr(sticker->already());
|
||||
sticker->sticker()->img = ImagePtr(sticker->already());
|
||||
} else {
|
||||
sticker->sticker->img = ImagePtr(sticker->data);
|
||||
sticker->sticker()->img = ImagePtr(sticker->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1240,12 +1252,12 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
|
||||
QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
|
||||
if (goodThumb) {
|
||||
p.drawPixmapLeft(ppos, width(), sticker->thumb->pix(w, h));
|
||||
} else if (!sticker->sticker->img->isNull()) {
|
||||
p.drawPixmapLeft(ppos, width(), sticker->sticker->img->pix(w, h));
|
||||
} else if (!sticker->sticker()->img->isNull()) {
|
||||
p.drawPixmapLeft(ppos, width(), sticker->sticker()->img->pix(w, h));
|
||||
}
|
||||
|
||||
if (hover > 0 && _setIds[c] == RecentStickerSetId && _custom.at(index)) {
|
||||
float64 xHover = _hovers[c][_sets[c].size() + index];
|
||||
if (hover > 0 && _sets[c].id == RecentStickerSetId && _custom.at(index)) {
|
||||
float64 xHover = _sets[c].hovers[_sets[c].pack.size() + index];
|
||||
|
||||
QPoint xPos = pos + QPoint(st::stickerPanSize.width() - st::stickerPanDelete.pxWidth(), 0);
|
||||
p.setOpacity(hover * (xHover + (1 - xHover) * st::stickerPanDeleteOpacity));
|
||||
@@ -1258,7 +1270,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
|
||||
if (y - st::emojiPanHeader < _top) {
|
||||
p.fillRect(QRect(0, qMin(_top, tilly - int(st::emojiPanHeader)), width(), st::emojiPanHeader), st::emojiPanHeaderBg->b);
|
||||
} else if (!special && y >= _top + 2 * st::emojiPanHeader) {
|
||||
p.setOpacity(st::stickerPanDeleteOpacity + (1 - st::stickerPanDeleteOpacity) * _hovers[c][size]);
|
||||
p.setOpacity(st::stickerPanDeleteOpacity + (1 - st::stickerPanDeleteOpacity) * _sets[c].hovers[size]);
|
||||
p.drawSpriteRight(QPoint(st::emojiPanHeaderLeft, y - (st::emojiPanHeader + st::notifyClose.icon.pxHeight()) / 2), width(), st::notifyClose.icon);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
@@ -1293,15 +1305,15 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
emit switchToEmoji();
|
||||
return;
|
||||
}
|
||||
if (_selected >= MatrixRowShift * _setIds.size()) {
|
||||
if (_selected >= MatrixRowShift * _sets.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int tab = (_selected / MatrixRowShift), sel = _selected % MatrixRowShift;
|
||||
if (_setIds[tab] == RecentStickerSetId && sel >= _sets[tab].size() && sel < _sets[tab].size() * 2 && _custom.at(sel - _sets[tab].size())) {
|
||||
if (_sets[tab].id == RecentStickerSetId && sel >= _sets[tab].pack.size() && sel < _sets[tab].pack.size() * 2 && _custom.at(sel - _sets[tab].pack.size())) {
|
||||
clearSelection(true);
|
||||
bool refresh = false;
|
||||
DocumentData *sticker = _sets[tab].at(sel - _sets[tab].size());
|
||||
DocumentData *sticker = _sets[tab].pack.at(sel - _sets[tab].pack.size());
|
||||
RecentStickerPack &recent(cGetRecentStickers());
|
||||
for (int32 i = 0, l = recent.size(); i < l; ++i) {
|
||||
if (recent.at(i).first == sticker) {
|
||||
@@ -1333,10 +1345,10 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (sel < _sets[tab].size()) {
|
||||
emit selected(_sets[tab][sel]);
|
||||
} else if (sel == _sets[tab].size()) {
|
||||
emit removing(_setIds[tab]);
|
||||
if (sel < _sets[tab].pack.size()) {
|
||||
emit selected(_sets[tab].pack[sel]);
|
||||
} else if (sel == _sets[tab].pack.size()) {
|
||||
emit removing(_sets[tab].id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1363,7 +1375,7 @@ void StickerPanInner::clearSelection(bool fast) {
|
||||
if (fast) {
|
||||
for (Animations::const_iterator i = _animations.cbegin(); i != _animations.cend(); ++i) {
|
||||
int index = qAbs(i.key()) - 1, tab = (index / MatrixRowShift), sel = index % MatrixRowShift;
|
||||
(index == SwitcherSelected ? _switcherHover : _hovers[tab][sel]) = 0;
|
||||
(index == SwitcherSelected ? _switcherHover : _sets[tab].hovers[sel]) = 0;
|
||||
}
|
||||
_animations.clear();
|
||||
_selected = _pressedSel = -1;
|
||||
@@ -1377,14 +1389,9 @@ void StickerPanInner::refreshStickers() {
|
||||
clearSelection(true);
|
||||
|
||||
const StickerSets &sets(cStickerSets());
|
||||
_setIds.clear(); _setIds.reserve(sets.size() + 1);
|
||||
_sets.clear(); _sets.reserve(sets.size() + 1);
|
||||
_hovers.clear(); _hovers.reserve(sets.size() + 1);
|
||||
_titles.clear(); _titles.reserve(sets.size() + 1);
|
||||
|
||||
refreshRecent(false);
|
||||
|
||||
appendSet(DefaultStickerSetId);
|
||||
for (StickerSetsOrder::const_iterator i = cStickerSetsOrder().cbegin(), e = cStickerSetsOrder().cend(); i != e; ++i) {
|
||||
appendSet(*i);
|
||||
}
|
||||
@@ -1400,11 +1407,11 @@ void StickerPanInner::refreshStickers() {
|
||||
void StickerPanInner::preloadImages() {
|
||||
uint64 ms = getms();
|
||||
for (int32 i = 0, l = _sets.size(), k = 0; i < l; ++i) {
|
||||
for (int32 j = 0, n = _sets.at(i).size(); j < n; ++j) {
|
||||
for (int32 j = 0, n = _sets.at(i).pack.size(); j < n; ++j) {
|
||||
if (++k > StickerPanPerRow * (StickerPanPerRow + 1)) break;
|
||||
|
||||
DocumentData *sticker = _sets.at(i).at(j);
|
||||
if (!sticker || !sticker->sticker) continue;
|
||||
DocumentData *sticker = _sets.at(i).pack.at(j);
|
||||
if (!sticker || !sticker->sticker()) continue;
|
||||
|
||||
bool goodThumb = !sticker->thumb->isNull() && ((sticker->thumb->width() >= 128) || (sticker->thumb->height() >= 128));
|
||||
if (goodThumb) {
|
||||
@@ -1430,14 +1437,14 @@ void StickerPanInner::preloadImages() {
|
||||
uint64 StickerPanInner::currentSet(int yOffset) const {
|
||||
int y, ytill = 0;
|
||||
for (int i = 0, l = _sets.size(); i < l; ++i) {
|
||||
int cnt = _sets.at(i).size();
|
||||
int cnt = _sets.at(i).pack.size();
|
||||
y = ytill;
|
||||
ytill = y + st::emojiPanHeader + ((cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0)) * st::stickerPanSize.height();
|
||||
if (yOffset < ytill) {
|
||||
return _setIds.at(i);
|
||||
return _sets.at(i).id;
|
||||
}
|
||||
}
|
||||
return _setIds.isEmpty() ? RecentStickerSetId : _setIds.back();
|
||||
return _sets.isEmpty() ? RecentStickerSetId : _sets.back().id;
|
||||
}
|
||||
|
||||
void StickerPanInner::appendSet(uint64 setId) {
|
||||
@@ -1450,11 +1457,9 @@ void StickerPanInner::appendSet(uint64 setId) {
|
||||
for (int32 i = 0, l = it->stickers.size(); i < l; ++i) {
|
||||
pack.push_back(it->stickers.at(i));
|
||||
}
|
||||
_setIds.push_back(it->id);
|
||||
_sets.push_back(pack);
|
||||
_hovers.push_back(QVector<float64>(it->stickers.size() + 1, 0));
|
||||
int32 availw = width() - st::emojiPanHeaderLeft - st::emojiSwitchSkip - _emojiWidth - (st::emojiSwitchSkip - st::emojiSwitchImgSkip);
|
||||
_titles.push_back(st::emojiPanHeaderFont->m.elidedText(it->title, Qt::ElideRight, availw));
|
||||
QString title = st::emojiPanHeaderFont->m.elidedText(it->title, Qt::ElideRight, availw);
|
||||
_sets.push_back(DisplayedSet(it->id, it->flags, title, pack.size() + 1, pack));
|
||||
}
|
||||
|
||||
void StickerPanInner::refreshRecent(bool performResize) {
|
||||
@@ -1462,11 +1467,8 @@ void StickerPanInner::refreshRecent(bool performResize) {
|
||||
clearSelection(true);
|
||||
StickerSets::const_iterator customIt = cStickerSets().constFind(CustomStickerSetId);
|
||||
if (cGetRecentStickers().isEmpty() && (customIt == cStickerSets().cend() || customIt->stickers.isEmpty())) {
|
||||
if (!_setIds.isEmpty() && _setIds.at(0) == RecentStickerSetId) {
|
||||
_setIds.pop_front();
|
||||
if (!_sets.isEmpty() && _sets.at(0).id == RecentStickerSetId) {
|
||||
_sets.pop_front();
|
||||
_hovers.pop_front();
|
||||
_titles.pop_front();
|
||||
}
|
||||
} else {
|
||||
StickerPack recent;
|
||||
@@ -1489,14 +1491,11 @@ void StickerPanInner::refreshRecent(bool performResize) {
|
||||
_custom.push_back(true);
|
||||
}
|
||||
}
|
||||
if (_setIds.isEmpty() || _setIds.at(0) != RecentStickerSetId) {
|
||||
_setIds.push_front(RecentStickerSetId);
|
||||
_hovers.push_back(QVector<float64>(recent.size() * 2, 0));
|
||||
_sets.push_back(recent);
|
||||
_titles.push_back(lang(lng_emoji_category0));
|
||||
if (_sets.isEmpty() || _sets.at(0).id != RecentStickerSetId) {
|
||||
_sets.push_back(DisplayedSet(RecentStickerSetId, MTPDstickerSet_flag_official, lang(lng_emoji_category0), recent.size() * 2, recent));
|
||||
} else {
|
||||
_sets[0] = recent;
|
||||
_hovers[0].resize(recent.size() * 2);
|
||||
_sets[0].pack = recent;
|
||||
_sets[0].hovers.resize(recent.size() * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1510,14 +1509,14 @@ void StickerPanInner::refreshRecent(bool performResize) {
|
||||
|
||||
void StickerPanInner::fillIcons(QVector<StickerIcon> &icons) {
|
||||
icons.clear();
|
||||
if (_setIds.isEmpty()) return;
|
||||
if (_sets.isEmpty()) return;
|
||||
|
||||
icons.reserve(_sets.size());
|
||||
int32 i = 0;
|
||||
if (_setIds.at(0) == RecentStickerSetId) ++i;
|
||||
if (_sets.at(0).id == RecentStickerSetId) ++i;
|
||||
if (i > 0) icons.push_back(StickerIcon());
|
||||
for (int32 l = _sets.size(); i < l; ++i) {
|
||||
DocumentData *s = _sets.at(i).at(0);
|
||||
DocumentData *s = _sets.at(i).pack.at(0);
|
||||
int32 availw = st::rbEmoji.width - 2 * st::stickerIconPadding, availh = st::rbEmoji.height - 2 * st::stickerIconPadding;
|
||||
int32 thumbw = s->thumb->width(), thumbh = s->thumb->height(), pixw = 1, pixh = 1;
|
||||
if (availw * thumbh > availh * thumbw) {
|
||||
@@ -1529,7 +1528,7 @@ void StickerPanInner::fillIcons(QVector<StickerIcon> &icons) {
|
||||
}
|
||||
if (pixw < 1) pixw = 1;
|
||||
if (pixh < 1) pixh = 1;
|
||||
icons.push_back(StickerIcon(_setIds.at(i), s, pixw, pixh));
|
||||
icons.push_back(StickerIcon(_sets.at(i).id, s, pixw, pixh));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1547,25 +1546,27 @@ void StickerPanInner::updateSelected() {
|
||||
}
|
||||
} else {
|
||||
int y, ytill = 0, sx = (rtl() ? width() - p.x() : p.x()) - st::stickerPanPadding;
|
||||
for (int c = 0, l = _setIds.size(); c < l; ++c) {
|
||||
int cnt = _sets[c].size();
|
||||
bool special = _setIds[c] == DefaultStickerSetId || _setIds[c] == RecentStickerSetId;
|
||||
for (int c = 0, l = _sets.size(); c < l; ++c) {
|
||||
const DisplayedSet &set(_sets.at(c));
|
||||
int cnt = set.pack.size();
|
||||
bool special = (set.flags & MTPDstickerSet_flag_official);
|
||||
|
||||
y = ytill;
|
||||
ytill = y + st::emojiPanHeader + ((cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0)) * st::stickerPanSize.height();
|
||||
if (p.y() >= y && p.y() < ytill) {
|
||||
if (!special && p.y() >= y && p.y() < y + st::emojiPanHeader && sx + st::stickerPanPadding >= width() - st::emojiPanHeaderLeft - st::notifyClose.icon.pxWidth() && sx + st::stickerPanPadding < width() - st::emojiPanHeaderLeft) {
|
||||
selIndex = c * MatrixRowShift + _sets[c].size();
|
||||
selIndex = c * MatrixRowShift + set.pack.size();
|
||||
} else {
|
||||
y += st::emojiPanHeader;
|
||||
if (p.y() >= y && sx >= 0 && sx < StickerPanPerRow * st::stickerPanSize.width()) {
|
||||
selIndex = qFloor((p.y() - y) / st::stickerPanSize.height()) * StickerPanPerRow + qFloor(sx / st::stickerPanSize.width());
|
||||
if (selIndex >= _sets[c].size()) {
|
||||
if (selIndex >= set.pack.size()) {
|
||||
selIndex = -1;
|
||||
} else {
|
||||
if (_setIds[c] == RecentStickerSetId && _custom[selIndex]) {
|
||||
if (set.id == RecentStickerSetId && _custom[selIndex]) {
|
||||
int32 inx = sx - (selIndex % StickerPanPerRow) * st::stickerPanSize.width(), iny = p.y() - y - ((selIndex / StickerPanPerRow) * st::stickerPanSize.height());
|
||||
if (inx >= st::stickerPanSize.width() - st::stickerPanDelete.pxWidth() && iny < st::stickerPanDelete.pxHeight()) {
|
||||
selIndex += _sets[c].size();
|
||||
selIndex += set.pack.size();
|
||||
}
|
||||
}
|
||||
selIndex += c * MatrixRowShift;
|
||||
@@ -1579,13 +1580,13 @@ void StickerPanInner::updateSelected() {
|
||||
|
||||
bool startanim = false;
|
||||
int oldSel = _selected, oldSelTab = oldSel / MatrixRowShift, xOldSel = -1, newSel = selIndex, newSelTab = newSel / MatrixRowShift, xNewSel = -1;
|
||||
if (oldSel >= 0 && oldSelTab < _setIds.size() && _setIds[oldSelTab] == RecentStickerSetId && oldSel >= oldSelTab * MatrixRowShift + _sets[oldSelTab].size()) {
|
||||
if (oldSel >= 0 && oldSelTab < _sets.size() && _sets[oldSelTab].id == RecentStickerSetId && oldSel >= oldSelTab * MatrixRowShift + _sets[oldSelTab].pack.size()) {
|
||||
xOldSel = oldSel;
|
||||
oldSel -= _sets[oldSelTab].size();
|
||||
oldSel -= _sets[oldSelTab].pack.size();
|
||||
}
|
||||
if (newSel >= 0 && newSelTab < _setIds.size() && _setIds[newSelTab] == RecentStickerSetId && newSel >= newSelTab * MatrixRowShift + _sets[newSelTab].size()) {
|
||||
if (newSel >= 0 && newSelTab < _sets.size() && _sets[newSelTab].id == RecentStickerSetId && newSel >= newSelTab * MatrixRowShift + _sets[newSelTab].pack.size()) {
|
||||
xNewSel = newSel;
|
||||
newSel -= _sets[newSelTab].size();
|
||||
newSel -= _sets[newSelTab].pack.size();
|
||||
}
|
||||
if (newSel != oldSel) {
|
||||
if (oldSel >= 0) {
|
||||
@@ -1630,10 +1631,10 @@ bool StickerPanInner::animStep(float64 ms) {
|
||||
int index = qAbs(i.key()) - 1, tab = (index / MatrixRowShift), sel = index % MatrixRowShift;
|
||||
float64 dt = float64(now - i.value()) / st::emojiPanDuration;
|
||||
if (dt >= 1) {
|
||||
(index == SwitcherSelected ? _switcherHover : _hovers[tab][sel]) = (i.key() > 0) ? 1 : 0;
|
||||
(index == SwitcherSelected ? _switcherHover : _sets[tab].hovers[sel]) = (i.key() > 0) ? 1 : 0;
|
||||
i = _animations.erase(i);
|
||||
} else {
|
||||
(index == SwitcherSelected ? _switcherHover : _hovers[tab][sel]) = (i.key() > 0) ? dt : (1 - dt);
|
||||
(index == SwitcherSelected ? _switcherHover : _sets[tab].hovers[sel]) = (i.key() > 0) ? dt : (1 - dt);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
@@ -1645,9 +1646,9 @@ void StickerPanInner::showStickerSet(uint64 setId) {
|
||||
clearSelection(true);
|
||||
|
||||
int32 y = 0;
|
||||
for (int c = 0; c < _setIds.size(); ++c) {
|
||||
if (_setIds.at(c) == setId) break;
|
||||
int rows = (_sets[c].size() / StickerPanPerRow) + ((_sets[c].size() % StickerPanPerRow) ? 1 : 0);
|
||||
for (int c = 0; c < _sets.size(); ++c) {
|
||||
if (_sets.at(c).id == setId) break;
|
||||
int rows = (_sets[c].pack.size() / StickerPanPerRow) + ((_sets[c].pack.size() % StickerPanPerRow) ? 1 : 0);
|
||||
y += st::emojiPanHeader + rows * st::stickerPanSize.height();
|
||||
}
|
||||
|
||||
@@ -1658,7 +1659,7 @@ void StickerPanInner::showStickerSet(uint64 setId) {
|
||||
update();
|
||||
}
|
||||
|
||||
EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent),
|
||||
EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent), _maxHeight(st::emojiPanMaxHeight),
|
||||
_horizontal(false), _noTabUpdate(false), _hiding(false), a_opacity(0), _shadow(st::dropdownDef.shadow),
|
||||
_recent(this , qsl("emoji_group"), dbietRecent , QString(), true , st::rbEmojiRecent),
|
||||
_people(this , qsl("emoji_group"), dbietPeople , QString(), false, st::rbEmojiPeople),
|
||||
@@ -1679,12 +1680,12 @@ e_scroll(this, st::emojiScroll), e_inner(), s_scroll(this, st::emojiScroll), s_i
|
||||
s_scroll.setFocusPolicy(Qt::NoFocus);
|
||||
s_scroll.viewport()->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
_width = st::dropdownDef.padding.left() + st::emojiPanFullSize.width() + st::dropdownDef.padding.right();
|
||||
_height = st::dropdownDef.padding.top() + st::emojiPanFullSize.height() + st::dropdownDef.padding.bottom();
|
||||
_width = st::dropdownDef.padding.left() + st::emojiPanWidth + st::dropdownDef.padding.right();
|
||||
_height = st::dropdownDef.padding.top() + _maxHeight + st::dropdownDef.padding.bottom();
|
||||
resize(_width, _height);
|
||||
|
||||
e_scroll.resize(st::emojiPanFullSize.width(), st::emojiPanFullSize.height() - st::rbEmoji.height);
|
||||
s_scroll.resize(st::emojiPanFullSize.width(), st::emojiPanFullSize.height() - st::rbEmoji.height);
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
|
||||
e_scroll.move(st::dropdownDef.padding.left(), st::dropdownDef.padding.top());
|
||||
e_scroll.setWidget(&e_inner);
|
||||
@@ -1696,8 +1697,8 @@ e_scroll(this, st::emojiScroll), e_inner(), s_scroll(this, st::emojiScroll), s_i
|
||||
s_inner.setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
s_scroll.setAutoFillBackground(true);
|
||||
|
||||
int32 left = _iconsLeft = st::dropdownDef.padding.left() + (st::emojiPanFullSize.width() - 8 * st::rbEmoji.width) / 2;
|
||||
int32 top = _iconsTop = st::dropdownDef.padding.top() + st::emojiPanFullSize.height() - st::rbEmoji.height;
|
||||
int32 left = _iconsLeft = st::dropdownDef.padding.left() + (st::emojiPanWidth - 8 * st::rbEmoji.width) / 2;
|
||||
int32 top = _iconsTop = st::dropdownDef.padding.top() + _maxHeight - st::rbEmoji.height;
|
||||
prepareTab(left, top, _width, _recent);
|
||||
prepareTab(left, top, _width, _people);
|
||||
prepareTab(left, top, _width, _nature);
|
||||
@@ -1735,6 +1736,41 @@ e_scroll(this, st::emojiScroll), e_inner(), s_scroll(this, st::emojiScroll), s_i
|
||||
// setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
}
|
||||
|
||||
void EmojiPan::setMaxHeight(int32 h) {
|
||||
h = qMin(int(st::emojiPanMaxHeight), h);
|
||||
if (h == _maxHeight) return;
|
||||
|
||||
int32 was = _maxHeight;
|
||||
_maxHeight = h;
|
||||
|
||||
_height = st::dropdownDef.padding.top() + _maxHeight + st::dropdownDef.padding.bottom();
|
||||
resize(_width, _height);
|
||||
|
||||
if (was > _maxHeight) {
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_inner.setMaxHeight(_maxHeight);
|
||||
e_inner.setMaxHeight(_maxHeight);
|
||||
} else {
|
||||
s_inner.setMaxHeight(_maxHeight);
|
||||
e_inner.setMaxHeight(_maxHeight);
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
}
|
||||
|
||||
_iconsTop = st::dropdownDef.padding.top() + _maxHeight - st::rbEmoji.height;
|
||||
_recent.move(_recent.x(), _iconsTop);
|
||||
_people.move(_people.x(), _iconsTop);
|
||||
_nature.move(_nature.x(), _iconsTop);
|
||||
_food.move(_food.x(), _iconsTop);
|
||||
_celebration.move(_celebration.x(), _iconsTop);
|
||||
_activity.move(_activity.x(), _iconsTop);
|
||||
_travel.move(_travel.x(), _iconsTop);
|
||||
_objects.move(_objects.x(), _iconsTop);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void EmojiPan::prepareTab(int32 &left, int32 top, int32 _width, FlatRadiobutton &tab) {
|
||||
tab.moveToLeft(left, top, _width);
|
||||
left += tab.width();
|
||||
@@ -2362,9 +2398,9 @@ void EmojiPan::onSwitch() {
|
||||
hideAll();
|
||||
_moveStart = getms();
|
||||
|
||||
a_toCoord = (_stickersShown != rtl()) ? anim::ivalue(st::emojiPanFullSize.width(), 0) : anim::ivalue(-st::emojiPanFullSize.width(), 0);
|
||||
a_toCoord = (_stickersShown != rtl()) ? anim::ivalue(st::emojiPanWidth, 0) : anim::ivalue(-st::emojiPanWidth, 0);
|
||||
a_toAlpha = anim::fvalue(0, 1);
|
||||
a_fromCoord = (_stickersShown != rtl()) ? anim::ivalue(0, -st::emojiPanFullSize.width()) : anim::ivalue(0, st::emojiPanFullSize.width());
|
||||
a_fromCoord = (_stickersShown != rtl()) ? anim::ivalue(0, -st::emojiPanWidth) : anim::ivalue(0, st::emojiPanWidth);
|
||||
a_fromAlpha = anim::fvalue(1, 0);
|
||||
|
||||
if (!animating()) anim::start(this);
|
||||
@@ -2373,7 +2409,7 @@ void EmojiPan::onSwitch() {
|
||||
|
||||
void EmojiPan::onRemoveSet(uint64 setId) {
|
||||
StickerSets::const_iterator it = cStickerSets().constFind(setId);
|
||||
if (it != cStickerSets().cend() && setId != DefaultStickerSetId && setId != RecentStickerSetId) {
|
||||
if (it != cStickerSets().cend() && !(it->flags & MTPDstickerSet_flag_official)) {
|
||||
_removingSetId = it->id;
|
||||
ConfirmBox *box = new ConfirmBox(lng_stickers_remove_pack(lt_sticker_pack, it->title));
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onRemoveSetSure()));
|
||||
@@ -2385,7 +2421,7 @@ void EmojiPan::onRemoveSet(uint64 setId) {
|
||||
void EmojiPan::onRemoveSetSure() {
|
||||
App::wnd()->hideLayer();
|
||||
StickerSets::iterator it = cRefStickerSets().find(_removingSetId);
|
||||
if (it != cRefStickerSets().cend() && _removingSetId != DefaultStickerSetId && _removingSetId != RecentStickerSetId) {
|
||||
if (it != cRefStickerSets().cend() && !(it->flags & MTPDstickerSet_flag_official)) {
|
||||
if (it->id && it->access) {
|
||||
MTP::send(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access))));
|
||||
} else if (!it->shortName.isEmpty()) {
|
||||
@@ -2425,7 +2461,8 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
|
||||
QPainter p(this);
|
||||
|
||||
int32 atwidth = st::mentionFont->m.width('@'), hashwidth = st::mentionFont->m.width('#');
|
||||
int32 availwidth = width() - 2 * st::mentionPadding.left() - st::mentionPhotoSize - 2 * st::mentionPadding.right();
|
||||
int32 mentionleft = 2 * st::mentionPadding.left() + st::mentionPhotoSize;
|
||||
int32 mentionwidth = width() - mentionleft - 2 * st::mentionPadding.right();
|
||||
int32 htagleft = st::btnAttachPhoto.width + st::taMsgField.textMrg.left() - st::dlgShadow, htagwidth = width() - st::mentionPadding.right() - htagleft - st::mentionScroll.width;
|
||||
|
||||
int32 from = qFloor(e->rect().top() / st::mentionHeight), to = qFloor(e->rect().bottom() / st::mentionHeight) + 1;
|
||||
@@ -2445,9 +2482,9 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
|
||||
UserData *user = _rows->at(i);
|
||||
QString first = (_parent->filter().size() < 2) ? QString() : ('@' + user->username.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('@' + user->username) : user->username.mid(_parent->filter().size() - 1);
|
||||
int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second), unamewidth = firstwidth + secondwidth, namewidth = user->nameText.maxWidth();
|
||||
if (availwidth < unamewidth + namewidth) {
|
||||
namewidth = (availwidth * namewidth) / (namewidth + unamewidth);
|
||||
unamewidth = availwidth - namewidth;
|
||||
if (mentionwidth < unamewidth + namewidth) {
|
||||
namewidth = (mentionwidth * namewidth) / (namewidth + unamewidth);
|
||||
unamewidth = mentionwidth - namewidth;
|
||||
if (firstwidth < unamewidth + st::mentionFont->elidew) {
|
||||
if (firstwidth < unamewidth) {
|
||||
first = st::mentionFont->m.elidedText(first, Qt::ElideRight, unamewidth);
|
||||
@@ -2465,10 +2502,10 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
|
||||
|
||||
p.setFont(st::mentionFont->f);
|
||||
p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p);
|
||||
p.drawText(2 * st::mentionPadding.left() + st::mentionPhotoSize + namewidth + st::mentionPadding.right(), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first);
|
||||
p.drawText(mentionleft + namewidth + st::mentionPadding.right(), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first);
|
||||
if (!second.isEmpty()) {
|
||||
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
|
||||
p.drawText(2 * st::mentionPadding.left() + st::mentionPhotoSize + namewidth + st::mentionPadding.right() + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second);
|
||||
p.drawText(mentionleft + namewidth + st::mentionPadding.right() + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second);
|
||||
}
|
||||
} else if (!_hrows->isEmpty()) {
|
||||
QString hrow = _hrows->at(i);
|
||||
@@ -2495,50 +2532,42 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
|
||||
} else {
|
||||
UserData *user = _crows->at(i).first;
|
||||
|
||||
const BotCommand &command = _crows->at(i).second;
|
||||
QString toHighlight = command.command;
|
||||
const BotCommand *command = _crows->at(i).second;
|
||||
QString toHighlight = command->command;
|
||||
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : -1;
|
||||
if (hasUsername || botStatus == 0 || botStatus == 2) {
|
||||
toHighlight += '@' + user->username;
|
||||
}
|
||||
if (_parent->chat() || botStatus == 0 || botStatus == 2) {
|
||||
if (true || _parent->chat() || botStatus == 0 || botStatus == 2) {
|
||||
user->photo->load();
|
||||
p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pixRounded(st::mentionPhotoSize));
|
||||
}
|
||||
|
||||
int32 addleft = 0, widthleft = htagwidth;
|
||||
int32 addleft = 0, widthleft = mentionwidth;
|
||||
QString first = (_parent->filter().size() < 2) ? QString() : ('/' + toHighlight.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('/' + toHighlight) : toHighlight.mid(_parent->filter().size() - 1);
|
||||
int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second);
|
||||
if (htagwidth < firstwidth + secondwidth) {
|
||||
if (htagwidth < firstwidth + st::mentionFont->elidew) {
|
||||
first = st::mentionFont->m.elidedText(first + second, Qt::ElideRight, htagwidth);
|
||||
if (widthleft < firstwidth + secondwidth) {
|
||||
if (widthleft < firstwidth + st::mentionFont->elidew) {
|
||||
first = st::mentionFont->m.elidedText(first + second, Qt::ElideRight, widthleft);
|
||||
second = QString();
|
||||
} else {
|
||||
second = st::mentionFont->m.elidedText(second, Qt::ElideRight, htagwidth - firstwidth);
|
||||
second = st::mentionFont->m.elidedText(second, Qt::ElideRight, widthleft - firstwidth);
|
||||
}
|
||||
}
|
||||
p.setFont(st::mentionFont->f);
|
||||
if (!first.isEmpty()) {
|
||||
p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p);
|
||||
p.drawText(htagleft, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first);
|
||||
p.drawText(mentionleft, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first);
|
||||
}
|
||||
if (!second.isEmpty()) {
|
||||
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
|
||||
p.drawText(htagleft + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second);
|
||||
p.drawText(mentionleft + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second);
|
||||
}
|
||||
addleft += firstwidth + secondwidth + st::mentionPadding.left();
|
||||
widthleft -= firstwidth + secondwidth + st::mentionPadding.left();
|
||||
|
||||
QString description = command.description;
|
||||
if (widthleft > st::mentionFont->elidew && !description.isEmpty()) {
|
||||
p.setFont(st::mentionFont->f);
|
||||
int32 descwidth = st::mentionFont->m.width(description);
|
||||
if (widthleft < descwidth) {
|
||||
description = st::mentionFont->m.elidedText(description, Qt::ElideRight, widthleft);
|
||||
descwidth = st::mentionFont->m.width(description);
|
||||
}
|
||||
if (widthleft > st::mentionFont->elidew && !command->descriptionText().isEmpty()) {
|
||||
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
|
||||
p.drawText(htagleft + addleft + (widthleft - descwidth), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, description);
|
||||
command->descriptionText().drawElided(p, mentionleft + addleft, i * st::mentionHeight + st::mentionTop, widthleft, 1, style::al_right);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2574,6 +2603,15 @@ bool MentionsInner::moveSel(int direction) {
|
||||
}
|
||||
|
||||
bool MentionsInner::select() {
|
||||
QString sel = getSelected();
|
||||
if (!sel.isEmpty()) {
|
||||
emit chosen(sel);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString MentionsInner::getSelected() const {
|
||||
int32 maxSel = (_rows->isEmpty() ? (_hrows->isEmpty() ? _crows->size() : _hrows->size()) : _rows->size());
|
||||
if (_sel >= 0 && _sel < maxSel) {
|
||||
QString result;
|
||||
@@ -2583,18 +2621,17 @@ bool MentionsInner::select() {
|
||||
result = '#' + _hrows->at(_sel);
|
||||
} else {
|
||||
UserData *user = _crows->at(_sel).first;
|
||||
const BotCommand &command(_crows->at(_sel).second);
|
||||
const BotCommand *command(_crows->at(_sel).second);
|
||||
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : -1;
|
||||
if (botStatus == 0 || botStatus == 2 || _parent->filter().indexOf('@') > 1) {
|
||||
result = '/' + command.command + '@' + user->username;
|
||||
result = '/' + command->command + '@' + user->username;
|
||||
} else {
|
||||
result = '/' + command.command;
|
||||
result = '/' + command->command;
|
||||
}
|
||||
}
|
||||
emit chosen(result);
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
return QString();
|
||||
}
|
||||
|
||||
void MentionsInner::mousePressEvent(QMouseEvent *e) {
|
||||
@@ -2720,6 +2757,12 @@ void MentionsDropdown::showFiltered(PeerData *peer, QString start) {
|
||||
updateFiltered(toDown);
|
||||
}
|
||||
|
||||
bool MentionsDropdown::clearFilteredCommands() {
|
||||
if (_crows.isEmpty()) return false;
|
||||
_crows.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
int32 now = unixtime();
|
||||
MentionRows rows;
|
||||
@@ -2783,6 +2826,7 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
}
|
||||
}
|
||||
} else if (_user->botInfo) {
|
||||
if (!_user->botInfo->inited) App::api()->requestFullPeer(_user);
|
||||
cnt = _user->botInfo->commands.size();
|
||||
bots.insert(_user, true);
|
||||
}
|
||||
@@ -2793,17 +2837,16 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
for (MentionRows::const_iterator i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
|
||||
UserData *user = *i;
|
||||
if (!user->botInfo) continue;
|
||||
if (!bots.contains(user)) continue;
|
||||
if (!user->botInfo->inited) App::api()->requestFullPeer(user);
|
||||
if (user->botInfo->commands.isEmpty()) continue;
|
||||
bots.remove(user);
|
||||
for (int32 j = 0, l = user->botInfo->commands.size(); j < l; ++j) {
|
||||
if (_filter.size() > 1) {
|
||||
QString toFilter = (hasUsername || botStatus == 0 || botStatus == 2) ? user->botInfo->commands.at(j).command + '@' + user->username : user->botInfo->commands.at(j).command;
|
||||
if (!toFilter.startsWith(_filter.midRef(1), Qt::CaseInsensitive) || toFilter.size() + 1 == _filter.size()) continue;
|
||||
if (!toFilter.startsWith(_filter.midRef(1), Qt::CaseInsensitive)/* || toFilter.size() + 1 == _filter.size()*/) continue;
|
||||
}
|
||||
crows.push_back(qMakePair(user, user->botInfo->commands.at(j)));
|
||||
}
|
||||
if (!bots.isEmpty()) {
|
||||
bots.remove(user);
|
||||
crows.push_back(qMakePair(user, &user->botInfo->commands.at(j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2813,9 +2856,9 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
for (int32 j = 0, l = user->botInfo->commands.size(); j < l; ++j) {
|
||||
if (_filter.size() > 1) {
|
||||
QString toFilter = (hasUsername || botStatus == 0 || botStatus == 2) ? user->botInfo->commands.at(j).command + '@' + user->username : user->botInfo->commands.at(j).command;
|
||||
if (!toFilter.startsWith(_filter.midRef(1), Qt::CaseInsensitive) || toFilter.size() + 1 == _filter.size()) continue;
|
||||
if (!toFilter.startsWith(_filter.midRef(1), Qt::CaseInsensitive)/* || toFilter.size() + 1 == _filter.size()*/) continue;
|
||||
}
|
||||
crows.push_back(qMakePair(user, user->botInfo->commands.at(j)));
|
||||
crows.push_back(qMakePair(user, &user->botInfo->commands.at(j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2824,10 +2867,10 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
if (rows.isEmpty() && hrows.isEmpty() && crows.isEmpty()) {
|
||||
if (!isHidden()) {
|
||||
hideStart();
|
||||
_rows.clear();
|
||||
_hrows.clear();
|
||||
_crows.clear();
|
||||
}
|
||||
_rows.clear();
|
||||
_hrows.clear();
|
||||
_crows.clear();
|
||||
} else {
|
||||
_rows = rows;
|
||||
_hrows = hrows;
|
||||
@@ -2857,13 +2900,13 @@ void MentionsDropdown::recount(bool toDown) {
|
||||
int32 h = (_rows.isEmpty() ? (_hrows.isEmpty() ? _crows.size() : _hrows.size()) : _rows.size()) * st::mentionHeight, oldst = _scroll.scrollTop(), st = oldst;
|
||||
|
||||
if (_inner.height() != h) {
|
||||
st += h - _inner.height();
|
||||
// st += h - _inner.height();
|
||||
_inner.resize(width(), h);
|
||||
}
|
||||
if (h > _boundings.height()) h = _boundings.height();
|
||||
if (h > 4.5 * st::mentionHeight) h = 4.5 * st::mentionHeight;
|
||||
if (height() != h) {
|
||||
st += _scroll.height() - h;
|
||||
// st += _scroll.height() - h;
|
||||
setGeometry(0, _boundings.height() - h, width(), h);
|
||||
_scroll.resize(width(), h);
|
||||
} else if (y() != _boundings.height() - h) {
|
||||
@@ -2954,6 +2997,10 @@ int32 MentionsDropdown::innerBottom() {
|
||||
return _scroll.scrollTop() + _scroll.height();
|
||||
}
|
||||
|
||||
QString MentionsDropdown::getSelected() const {
|
||||
return _inner.getSelected();
|
||||
}
|
||||
|
||||
bool MentionsDropdown::eventFilter(QObject *obj, QEvent *e) {
|
||||
if (isHidden()) return QWidget::eventFilter(obj, e);
|
||||
if (e->type() == QEvent::KeyPress) {
|
||||
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
|
||||
signals:
|
||||
|
||||
void dropped(QDropEvent *e);
|
||||
void dropped(const QMimeData *data);
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -202,6 +202,7 @@ public:
|
||||
|
||||
EmojiPanInner(QWidget *parent = 0);
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
@@ -244,6 +245,8 @@ signals:
|
||||
|
||||
private:
|
||||
|
||||
int32 _maxHeight;
|
||||
|
||||
int32 countHeight();
|
||||
void selectEmoji(EmojiPtr emoji);
|
||||
|
||||
@@ -286,6 +289,7 @@ public:
|
||||
|
||||
StickerPanInner(QWidget *parent = 0);
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
@@ -329,6 +333,8 @@ signals:
|
||||
|
||||
private:
|
||||
|
||||
int32 _maxHeight;
|
||||
|
||||
void appendSet(uint64 setId);
|
||||
|
||||
int32 countHeight();
|
||||
@@ -339,10 +345,16 @@ private:
|
||||
|
||||
int32 _top;
|
||||
|
||||
QList<QString> _titles;
|
||||
QList<uint64> _setIds;
|
||||
QList<StickerPack> _sets;
|
||||
QList<QVector<float64> > _hovers;
|
||||
struct DisplayedSet {
|
||||
DisplayedSet(uint64 id, int32 flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), hovers(hoversSize, 0), pack(pack) {
|
||||
}
|
||||
uint64 id;
|
||||
int32 flags;
|
||||
QString title;
|
||||
QVector<float64> hovers;
|
||||
StickerPack pack;
|
||||
};
|
||||
QList<DisplayedSet> _sets;
|
||||
QList<bool> _custom;
|
||||
|
||||
int32 _selected, _pressedSel;
|
||||
@@ -359,6 +371,7 @@ public:
|
||||
|
||||
EmojiPan(QWidget *parent);
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void enterEvent(QEvent *e);
|
||||
@@ -412,6 +425,7 @@ signals:
|
||||
|
||||
private:
|
||||
|
||||
int32 _maxHeight;
|
||||
bool _horizontal;
|
||||
|
||||
void leaveToChildEvent(QEvent *e);
|
||||
@@ -467,7 +481,7 @@ private:
|
||||
|
||||
typedef QList<UserData*> MentionRows;
|
||||
typedef QList<QString> HashtagRows;
|
||||
typedef QList<QPair<UserData*, BotCommand> > BotCommandRows;
|
||||
typedef QList<QPair<UserData*, const BotCommand*> > BotCommandRows;
|
||||
|
||||
class MentionsDropdown;
|
||||
class MentionsInner : public QWidget {
|
||||
@@ -489,6 +503,8 @@ public:
|
||||
bool moveSel(int direction);
|
||||
bool select();
|
||||
|
||||
QString getSelected() const;
|
||||
|
||||
signals:
|
||||
|
||||
void chosen(QString mentionOrHashtag);
|
||||
@@ -525,6 +541,7 @@ public:
|
||||
|
||||
void fastHide();
|
||||
|
||||
bool clearFilteredCommands();
|
||||
void showFiltered(PeerData *peer, QString start);
|
||||
void updateFiltered(bool toDown = false);
|
||||
void setBoundings(QRect boundings);
|
||||
@@ -538,6 +555,7 @@ public:
|
||||
int32 innerBottom();
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
QString getSelected() const;
|
||||
|
||||
~MentionsDropdown();
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ void filedialogInit() {
|
||||
if (cDialogLastPath().isEmpty()) {
|
||||
#ifdef Q_OS_WIN
|
||||
// hack to restore previous dir without hurting performance
|
||||
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
|
||||
settings.beginGroup(QLatin1String("Qt"));
|
||||
QByteArray sd = settings.value(QLatin1String("filedialog")).toByteArray();
|
||||
QSettings settings(QSettings::UserScope, qstr("QtProject"));
|
||||
settings.beginGroup(qstr("Qt"));
|
||||
QByteArray sd = settings.value(qstr("filedialog")).toByteArray();
|
||||
QDataStream stream(&sd, QIODevice::ReadOnly);
|
||||
if (!stream.atEnd()) {
|
||||
int version = 3, _QFileDialogMagic = 190;
|
||||
|
||||
@@ -128,7 +128,8 @@ int32 FlatTextarea::fakeMargin() const {
|
||||
|
||||
void FlatTextarea::paintEvent(QPaintEvent *e) {
|
||||
QPainter p(viewport());
|
||||
p.fillRect(rect(), _st.bgColor->b);
|
||||
QRect r(rect().intersected(e->rect()));
|
||||
p.fillRect(r, _st.bgColor->b);
|
||||
bool phDraw = _phVisible;
|
||||
if (animating()) {
|
||||
p.setOpacity(a_phAlpha.current());
|
||||
@@ -136,7 +137,7 @@ void FlatTextarea::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
if (phDraw) {
|
||||
p.save();
|
||||
p.setClipRect(rect());
|
||||
p.setClipRect(r);
|
||||
QRect phRect(_st.textMrg.left() - _fakeMargin + _st.phPos.x() + a_phLeft.current(), _st.textMrg.top() - _fakeMargin + _st.phPos.y(), width() - _st.textMrg.left() - _st.textMrg.right(), height() - _st.textMrg.top() - _st.textMrg.bottom());
|
||||
p.setFont(_st.font->f);
|
||||
p.setPen(a_phColor.current());
|
||||
@@ -174,7 +175,10 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
|
||||
|
||||
if (!text.isEmpty()) {
|
||||
QTextCharFormat format = fragment.charFormat();
|
||||
return emojiFromUrl(static_cast<const QTextImageFormat*>(&format)->name());
|
||||
QString imageName = static_cast<QTextImageFormat*>(&format)->name();
|
||||
if (imageName.startsWith(qstr("emoji://e."))) {
|
||||
return emojiFromUrl(imageName);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -303,7 +307,7 @@ void FlatTextarea::getSingleEmojiFragment(QString &text, QTextFragment &fragment
|
||||
}
|
||||
if (f.isImageFormat() && !t.isEmpty() && t.at(0).unicode() == QChar::ObjectReplacementCharacter) {
|
||||
QString imageName = static_cast<QTextImageFormat*>(&f)->name();
|
||||
if (imageName.startsWith(QLatin1String("emoji://e."))) {
|
||||
if (imageName.startsWith(qstr("emoji://e."))) {
|
||||
fragment = fr;
|
||||
text = t;
|
||||
return;
|
||||
@@ -387,7 +391,7 @@ QString FlatTextarea::getText(int32 start, int32 end) const {
|
||||
case QChar::ObjectReplacementCharacter:
|
||||
if (emojiText.isEmpty() && f.isImageFormat()) {
|
||||
QString imageName = static_cast<QTextImageFormat*>(&f)->name();
|
||||
if (imageName.startsWith(QLatin1String("emoji://e."))) {
|
||||
if (imageName.startsWith(qstr("emoji://e."))) {
|
||||
if (EmojiPtr emoji = emojiFromUrl(imageName)) {
|
||||
emojiText = emojiString(emoji);
|
||||
}
|
||||
@@ -530,17 +534,25 @@ void FlatTextarea::insertFromMimeData(const QMimeData *source) {
|
||||
}
|
||||
|
||||
void FlatTextarea::insertEmoji(EmojiPtr emoji, QTextCursor c) {
|
||||
c.removeSelectedText();
|
||||
|
||||
QPixmap img(App::emojiSingle(emoji, _st.font->height));
|
||||
QString url = qsl("emoji://e.") + QString::number(emojiKey(emoji), 16);
|
||||
document()->addResource(QTextDocument::ImageResource, QUrl(url), QVariant(img));
|
||||
QTextImageFormat imageFormat;
|
||||
imageFormat.setWidth(img.width() / cIntRetinaFactor());
|
||||
imageFormat.setHeight(img.height() / cIntRetinaFactor());
|
||||
imageFormat.setName(url);
|
||||
int32 ew = ESize + st::emojiPadding * cIntRetinaFactor() * 2, eh = _st.font->height * cIntRetinaFactor();
|
||||
imageFormat.setWidth(ew / cIntRetinaFactor());
|
||||
imageFormat.setHeight(eh / cIntRetinaFactor());
|
||||
imageFormat.setName(qsl("emoji://e.") + QString::number(emojiKey(emoji), 16));
|
||||
imageFormat.setVerticalAlignment(QTextCharFormat::AlignBaseline);
|
||||
c.insertImage(imageFormat);
|
||||
|
||||
static QString objectReplacement(QChar::ObjectReplacementCharacter);
|
||||
c.insertText(objectReplacement, imageFormat);
|
||||
}
|
||||
|
||||
QVariant FlatTextarea::loadResource(int type, const QUrl &name) {
|
||||
QString imageName = name.toDisplayString();
|
||||
if (imageName.startsWith(qstr("emoji://e."))) {
|
||||
if (EmojiPtr emoji = emojiFromUrl(imageName)) {
|
||||
return QVariant(App::emojiSingle(emoji, _st.font->height));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
|
||||
@@ -579,6 +591,10 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
|
||||
if (emoji) break;
|
||||
}
|
||||
if (emoji) {
|
||||
if (!document()->pageSize().isNull()) {
|
||||
document()->setPageSize(QSizeF(0, 0));
|
||||
}
|
||||
|
||||
QTextCursor c(doc->docHandle(), emojiPosition);
|
||||
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
|
||||
int32 removedUpto = c.position();
|
||||
@@ -608,6 +624,8 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
|
||||
}
|
||||
|
||||
void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int charsAdded) {
|
||||
if (_replacingEmojis) return;
|
||||
|
||||
if (!_links.isEmpty()) {
|
||||
bool changed = false;
|
||||
for (LinkRanges::iterator i = _links.begin(); i != _links.end();) {
|
||||
@@ -624,7 +642,7 @@ void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int
|
||||
if (changed) emit linksChanged();
|
||||
}
|
||||
|
||||
if (_replacingEmojis || document()->availableRedoSteps() > 0) return;
|
||||
if (document()->availableRedoSteps() > 0) return;
|
||||
|
||||
const int takeBack = 3;
|
||||
|
||||
@@ -636,7 +654,14 @@ void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int
|
||||
}
|
||||
if (charsAdded <= 0) return;
|
||||
|
||||
_insertions.push_back(Insertion(position, charsAdded));
|
||||
// _insertions.push_back(Insertion(position, charsAdded));
|
||||
_replacingEmojis = true;
|
||||
QSizeF s = document()->pageSize();
|
||||
processDocumentContentsChange(position, charsAdded);
|
||||
if (document()->pageSize() != s) {
|
||||
document()->setPageSize(s);
|
||||
}
|
||||
_replacingEmojis = false;
|
||||
}
|
||||
|
||||
void FlatTextarea::onDocumentContentsChanged() {
|
||||
@@ -647,6 +672,8 @@ void FlatTextarea::onDocumentContentsChanged() {
|
||||
_insertions.clear();
|
||||
} else {
|
||||
_replacingEmojis = true;
|
||||
QSizeF s = document()->pageSize();
|
||||
|
||||
do {
|
||||
Insertion i = _insertions.front();
|
||||
_insertions.pop_front();
|
||||
@@ -654,6 +681,10 @@ void FlatTextarea::onDocumentContentsChanged() {
|
||||
processDocumentContentsChange(i.first, i.second);
|
||||
}
|
||||
} while (!_insertions.isEmpty());
|
||||
|
||||
if (document()->pageSize() != s) {
|
||||
document()->setPageSize(s);
|
||||
}
|
||||
_replacingEmojis = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,8 @@ protected:
|
||||
return QTextEdit::leaveEvent(e);
|
||||
}
|
||||
|
||||
QVariant loadResource(int type, const QUrl &name);
|
||||
|
||||
private:
|
||||
|
||||
void getSingleEmojiFragment(QString &text, QTextFragment &fragment) const;
|
||||
|
||||
@@ -26,8 +26,17 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include <QtGui/QCursor>
|
||||
#include <QtGui/QFont>
|
||||
|
||||
inline QPoint rtlpoint(int x, int y, int outerw) {
|
||||
return QPoint(rtl() ? (outerw - x) : x, y);
|
||||
}
|
||||
inline QPoint rtlpoint(const QPoint &p, int outerw) {
|
||||
return rtl() ? QPoint(outerw - p.x(), p.y()) : p;
|
||||
}
|
||||
inline QRect rtlrect(int x, int y, int w, int h, int outerw) {
|
||||
return rtl() ? QRect(outerw - x - w, y, w, h) : QRect(x, y, w, h);
|
||||
return QRect(rtl() ? (outerw - x - w) : x, y, w, h);
|
||||
}
|
||||
inline QRect rtlrect(const QRect &r, int outerw) {
|
||||
return rtl() ? QRect(outerw - r.x() - r.width(), r.y(), r.width(), r.height()) : r;
|
||||
}
|
||||
inline QRect centerrect(const QRect &inRect, const QRect &rect) {
|
||||
return QRect(inRect.x() + (inRect.width() - rect.width()) / 2, inRect.y() + (inRect.height() - rect.height()) / 2, rect.width(), rect.height());
|
||||
|
||||
@@ -24,7 +24,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace {
|
||||
|
||||
const QRegularExpression _reDomain(QString::fromUtf8("(?<![\\w\\$\\-\\_%=\\.])(?:([a-zA-Z]+)://)?((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){1,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"), QRegularExpression::UseUnicodePropertiesOption);
|
||||
const QRegularExpression _reDomain(QString::fromUtf8("(?<![\\w\\$\\-\\_%=\\.])(?:([a-zA-Z]+)://)?((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){1,10}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"), QRegularExpression::UseUnicodePropertiesOption);
|
||||
const QRegularExpression _reExplicitDomain(QString::fromUtf8("(?<![\\w\\$\\-\\_%=\\.])(?:([a-zA-Z]+)://)((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){0,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"), QRegularExpression::UseUnicodePropertiesOption);
|
||||
const QRegularExpression _reMailName(qsl("[a-zA-Z\\-_\\.0-9]{1,256}$"));
|
||||
const QRegularExpression _reMailStart(qsl("^[a-zA-Z\\-_\\.0-9]{1,256}\\@"));
|
||||
@@ -863,7 +863,7 @@ public:
|
||||
}
|
||||
|
||||
void draw(int32 left, int32 top, int32 w, style::align align, int32 yFrom, int32 yTo, uint16 selectedFrom = 0, uint16 selectedTo = 0) {
|
||||
if (_t->_blocks.isEmpty()) return;
|
||||
if (_t->isEmpty()) return;
|
||||
|
||||
_blocksSize = _t->_blocks.size();
|
||||
if (!_textStyle) _initDefault();
|
||||
@@ -1043,7 +1043,7 @@ public:
|
||||
}
|
||||
|
||||
void drawElided(int32 left, int32 top, int32 w, style::align align, int32 lines, int32 yFrom, int32 yTo, int32 removeFromEnd) {
|
||||
if (lines <= 0) return;
|
||||
if (lines <= 0 || _t->isNull()) return;
|
||||
|
||||
if (yTo < 0 || (lines - 1) * _t->_font->height < yTo) {
|
||||
yTo = lines * _t->_font->height;
|
||||
@@ -1057,7 +1057,7 @@ public:
|
||||
_lnkX = x;
|
||||
_lnkY = y;
|
||||
_lnkResult = &_zeroLnk;
|
||||
if (_lnkX >= 0 && _lnkX < w && _lnkY >= 0) {
|
||||
if (!_t->isNull() && _lnkX >= 0 && _lnkX < w && _lnkY >= 0) {
|
||||
draw(0, 0, w, align, _lnkY, _lnkY + 1);
|
||||
}
|
||||
return *_lnkResult;
|
||||
@@ -1067,7 +1067,7 @@ public:
|
||||
lnk = TextLinkPtr();
|
||||
inText = false;
|
||||
|
||||
if (x >= 0 && x < w && y >= 0) {
|
||||
if (!_t->isNull() && x >= 0 && x < w && y >= 0) {
|
||||
_lnkX = x;
|
||||
_lnkY = y;
|
||||
_lnkResult = &lnk;
|
||||
@@ -1081,8 +1081,7 @@ public:
|
||||
symbol = 0;
|
||||
after = false;
|
||||
upon = false;
|
||||
|
||||
if (y >= 0) {
|
||||
if (!_t->isNull() && y >= 0) {
|
||||
_lnkX = x;
|
||||
_lnkY = y;
|
||||
_getSymbol = &symbol;
|
||||
@@ -1615,25 +1614,36 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
style::font applyFlags(int32 flags, const style::font &f) {
|
||||
style::font result = f;
|
||||
if (flags & TextBlockBold) result = result->bold();
|
||||
if (flags & TextBlockItalic) result = result->italic();
|
||||
if (flags & TextBlockUnderline) result = result->underline();
|
||||
return result;
|
||||
}
|
||||
|
||||
void eSetFont(ITextBlock *block) {
|
||||
style::font newFont = _t->_font;
|
||||
int flags = block->flags();
|
||||
if (!flags && block->lnkIndex()) {
|
||||
if (flags) {
|
||||
newFont = applyFlags(flags, _t->_font);
|
||||
}
|
||||
if (block->lnkIndex()) {
|
||||
const TextLinkPtr &l(_t->_links.at(block->lnkIndex() - 1));
|
||||
if (l == _overLnk) {
|
||||
if (l == _downLnk || !_downLnk) {
|
||||
flags = _textStyle->lnkOverFlags->flags();
|
||||
if (_t->_font != _textStyle->lnkOverFlags) newFont = _textStyle->lnkOverFlags;
|
||||
} else {
|
||||
flags = _textStyle->lnkFlags->flags();
|
||||
if (_t->_font != _textStyle->lnkFlags) newFont = _textStyle->lnkFlags;
|
||||
}
|
||||
} else {
|
||||
flags = _textStyle->lnkFlags->flags();
|
||||
if (_t->_font != _textStyle->lnkFlags) newFont = _textStyle->lnkFlags;
|
||||
}
|
||||
}
|
||||
if (flags & TextBlockBold) newFont = newFont->bold();
|
||||
if (flags & TextBlockItalic) newFont = newFont->italic();
|
||||
if (flags & TextBlockUnderline) newFont = newFont->underline();
|
||||
if (newFont != _f) {
|
||||
if (newFont->family() == _t->_font->family()) {
|
||||
newFont = applyFlags(flags | newFont->flags(), _t->_font);
|
||||
}
|
||||
_f = newFont;
|
||||
_e->fnt = _f->f;
|
||||
_e->resetFontEngineCache();
|
||||
|
||||
@@ -259,13 +259,23 @@ public:
|
||||
virtual QString encoded() const {
|
||||
return QString();
|
||||
}
|
||||
virtual const QLatin1String &type() const = 0;
|
||||
virtual ~ITextLink() {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#define TEXT_LINK_CLASS(ClassName) public: \
|
||||
const QLatin1String &type() const { \
|
||||
static const QLatin1String _type(qstr(#ClassName)); \
|
||||
return _type; \
|
||||
}
|
||||
|
||||
typedef QSharedPointer<ITextLink> TextLinkPtr;
|
||||
|
||||
class TextLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(TextLink)
|
||||
|
||||
public:
|
||||
|
||||
TextLink(const QString &url, bool fullDisplayed = true) : _url(url), _fullDisplayed(fullDisplayed) {
|
||||
@@ -289,7 +299,7 @@ public:
|
||||
|
||||
QString encoded() const {
|
||||
QUrl u(_url), good(u.isValid() ? u.toEncoded() : QString());
|
||||
QString result(good.isValid() ? good.toEncoded() : _url);
|
||||
QString result(good.isValid() ? QString::fromUtf8(good.toEncoded()) : _url);
|
||||
|
||||
if (!QRegularExpression(qsl("^[a-zA-Z]+://")).match(result).hasMatch()) { // no protocol
|
||||
return qsl("http://") + result;
|
||||
@@ -305,6 +315,8 @@ private:
|
||||
};
|
||||
|
||||
class EmailLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(EmailLink)
|
||||
|
||||
public:
|
||||
|
||||
EmailLink(const QString &email) : _email(email) {
|
||||
@@ -335,6 +347,8 @@ private:
|
||||
};
|
||||
|
||||
class MentionLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(MentionLink)
|
||||
|
||||
public:
|
||||
|
||||
MentionLink(const QString &tag) : _tag(tag) {
|
||||
@@ -361,6 +375,8 @@ private:
|
||||
};
|
||||
|
||||
class HashtagLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(HashtagLink)
|
||||
|
||||
public:
|
||||
|
||||
HashtagLink(const QString &tag) : _tag(tag) {
|
||||
@@ -387,6 +403,8 @@ private:
|
||||
};
|
||||
|
||||
class BotCommandLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(BotCommandLink)
|
||||
|
||||
public:
|
||||
|
||||
BotCommandLink(const QString &cmd) : _cmd(cmd) {
|
||||
@@ -485,6 +503,9 @@ public:
|
||||
bool isEmpty() const {
|
||||
return _text.isEmpty();
|
||||
}
|
||||
bool isNull() const {
|
||||
return !_font;
|
||||
}
|
||||
QString original(uint16 selectedFrom = 0, uint16 selectedTo = 0xFFFF, bool expandLinks = true) const;
|
||||
|
||||
bool lastDots(int32 dots, int32 maxdots = 3) { // hack for typing animation
|
||||
|
||||
@@ -17,20 +17,6 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class Widget : public QWidget {
|
||||
public:
|
||||
|
||||
Widget(QWidget *parent = 0) : QWidget(parent) {
|
||||
}
|
||||
void moveToLeft(int x, int y, int outerw) {
|
||||
move(rtl() ? (outerw - x - width()) : x, y);
|
||||
}
|
||||
void moveToRight(int x, int y, int outerw) {
|
||||
move(rtl() ? x : (outerw - x - width()), y);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
namespace App {
|
||||
const QPixmap &sprite();
|
||||
}
|
||||
@@ -119,14 +105,20 @@ public:
|
||||
void drawSpriteCenter(const QRect &in, const style::sprite &sprite) {
|
||||
return drawPixmap(QPoint(in.x() + (in.width() - sprite.pxWidth()) / 2, in.y() + (in.height() - sprite.pxHeight()) / 2), App::sprite(), sprite);
|
||||
}
|
||||
void drawSpriteCenterLeft(const QRect &in, int outerw, const style::sprite &sprite) {
|
||||
return drawPixmapLeft(QPoint(in.x() + (in.width() - sprite.pxWidth()) / 2, in.y() + (in.height() - sprite.pxHeight()) / 2), outerw, App::sprite(), sprite);
|
||||
}
|
||||
void drawSpriteCenterRight(const QRect &in, int outerw, const style::sprite &sprite) {
|
||||
return drawPixmapRight(QPoint(in.x() + (in.width() - sprite.pxWidth()) / 2, in.y() + (in.height() - sprite.pxHeight()) / 2), outerw, App::sprite(), sprite);
|
||||
}
|
||||
};
|
||||
|
||||
class TWidget : public Widget {
|
||||
class TWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
TWidget(QWidget *parent = 0) : Widget(parent) {
|
||||
TWidget(QWidget *parent = 0) : QWidget(parent) {
|
||||
}
|
||||
TWidget *tparent() {
|
||||
return qobject_cast<TWidget*>(parentWidget());
|
||||
@@ -140,6 +132,27 @@ public:
|
||||
virtual void enterFromChildEvent(QEvent *e) { // e -- from leaveEvent() of child TWidget
|
||||
}
|
||||
|
||||
void moveToLeft(int x, int y, int outerw) {
|
||||
move(rtl() ? (outerw - x - width()) : x, y);
|
||||
}
|
||||
void moveToRight(int x, int y, int outerw) {
|
||||
move(rtl() ? x : (outerw - x - width()), y);
|
||||
}
|
||||
QPoint myrtlpoint(int x, int y) const {
|
||||
return rtlpoint(x, y, width());
|
||||
}
|
||||
QPoint myrtlpoint(const QPoint p) const {
|
||||
return rtlpoint(p, width());
|
||||
}
|
||||
QRect myrtlrect(int x, int y, int w, int h) const {
|
||||
return rtlrect(x, y, w, h, width());
|
||||
}
|
||||
QRect myrtlrect(const QRect &r) {
|
||||
return rtlrect(r, width());
|
||||
}
|
||||
void rtlupdate(const QRect &r) {
|
||||
update(myrtlrect(r));
|
||||
}
|
||||
bool event(QEvent *e) {
|
||||
return QWidget::event(e);
|
||||
}
|
||||
@@ -149,12 +162,12 @@ protected:
|
||||
void enterEvent(QEvent *e) {
|
||||
TWidget *p(tparent());
|
||||
if (p) p->leaveToChildEvent(e);
|
||||
return Widget::enterEvent(e);
|
||||
return QWidget::enterEvent(e);
|
||||
}
|
||||
void leaveEvent(QEvent *e) {
|
||||
TWidget *p(tparent());
|
||||
if (p) p->enterFromChildEvent(e);
|
||||
return Widget::leaveEvent(e);
|
||||
return QWidget::leaveEvent(e);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,6 +106,7 @@ enum MediaOverviewType {
|
||||
OverviewVideos,
|
||||
OverviewDocuments,
|
||||
OverviewAudios,
|
||||
OverviewAudioDocuments,
|
||||
|
||||
OverviewCount
|
||||
};
|
||||
@@ -127,6 +128,7 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
||||
case OverviewVideos: return MTP_inputMessagesFilterVideo();
|
||||
case OverviewDocuments: return MTP_inputMessagesFilterDocument();
|
||||
case OverviewAudios: return MTP_inputMessagesFilterAudio();
|
||||
case OverviewAudioDocuments: return MTP_inputMessagesFilterAudioDocuments();
|
||||
default: type = OverviewCount; break;
|
||||
}
|
||||
return MTPMessagesFilter();
|
||||
@@ -254,6 +256,7 @@ struct History : public QList<HistoryBlock*> {
|
||||
bool lastKeyboardInited, lastKeyboardUsed;
|
||||
MsgId lastKeyboardId;
|
||||
PeerId lastKeyboardFrom;
|
||||
void clearLastKeyboard();
|
||||
|
||||
mtpRequestId sendRequestId;
|
||||
|
||||
@@ -285,6 +288,8 @@ struct History : public QList<HistoryBlock*> {
|
||||
MediaOverviewIds _overviewIds[OverviewCount];
|
||||
int32 _overviewCount[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
|
||||
|
||||
void eraseFromOverview(MediaOverviewType type, MsgId msgId);
|
||||
|
||||
static const int32 ScrollMax = INT_MAX;
|
||||
};
|
||||
|
||||
@@ -635,6 +640,12 @@ class HistoryReply; // dynamic_cast optimize
|
||||
class HistoryMessage; // dynamic_cast optimize
|
||||
class HistoryForwarded; // dynamic_cast optimize
|
||||
|
||||
enum HistoryCursorState {
|
||||
HistoryDefaultCursorState,
|
||||
HistoryInTextCursorState,
|
||||
HistoryInDateCursorState
|
||||
};
|
||||
|
||||
class HistoryMedia;
|
||||
class HistoryItem : public HistoryElem {
|
||||
public:
|
||||
@@ -697,9 +708,9 @@ public:
|
||||
virtual bool hasPoint(int32 x, int32 y) const {
|
||||
return false;
|
||||
}
|
||||
virtual void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const {
|
||||
virtual void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const {
|
||||
lnk = TextLinkPtr();
|
||||
inText = false;
|
||||
state = HistoryDefaultCursorState;
|
||||
}
|
||||
virtual void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const { // from text
|
||||
upon = hasPoint(x, y);
|
||||
@@ -717,8 +728,6 @@ public:
|
||||
}
|
||||
virtual void updateMedia(const MTPMessageMedia &media) {
|
||||
}
|
||||
virtual void updateStickerEmoji() {
|
||||
}
|
||||
|
||||
virtual QString selectedText(uint32 selection) const {
|
||||
return qsl("[-]");
|
||||
@@ -787,6 +796,8 @@ protected:
|
||||
};
|
||||
|
||||
class MessageLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(MessageLink)
|
||||
|
||||
public:
|
||||
MessageLink(PeerId peer, MsgId msgid) : _peer(peer), _msgid(msgid) {
|
||||
}
|
||||
@@ -827,7 +838,7 @@ public:
|
||||
w = qMin(width, _maxw);
|
||||
return _height;
|
||||
}
|
||||
virtual void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const = 0;
|
||||
virtual void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const = 0;
|
||||
virtual void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const = 0;
|
||||
virtual bool uploading() const {
|
||||
return false;
|
||||
@@ -847,10 +858,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool updateStickerEmoji() {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool animating() const {
|
||||
return false;
|
||||
}
|
||||
@@ -890,7 +897,7 @@ public:
|
||||
const QString inHistoryText() const;
|
||||
const Text &captionForClone() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
HistoryMedia *clone() const;
|
||||
|
||||
PhotoData *photo() const {
|
||||
@@ -922,6 +929,7 @@ private:
|
||||
};
|
||||
|
||||
QString formatSizeText(qint64 size);
|
||||
QString formatDownloadText(qint64 ready, qint64 total);
|
||||
QString formatDurationText(qint64 duration);
|
||||
|
||||
class HistoryVideo : public HistoryMedia {
|
||||
@@ -938,7 +946,8 @@ public:
|
||||
const QString inDialogsText() const;
|
||||
const QString inHistoryText() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
int32 countHeight(const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
bool uploading() const {
|
||||
return (data->status == FileUploading);
|
||||
}
|
||||
@@ -978,7 +987,7 @@ public:
|
||||
const QString inDialogsText() const;
|
||||
const QString inHistoryText() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
bool uploading() const {
|
||||
return (data->status == FileUploading);
|
||||
}
|
||||
@@ -1021,7 +1030,7 @@ public:
|
||||
bool uploading() const {
|
||||
return (data->status == FileUploading);
|
||||
}
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
HistoryMedia *clone() const;
|
||||
|
||||
DocumentData *document() {
|
||||
@@ -1038,6 +1047,9 @@ public:
|
||||
}
|
||||
ImagePtr replyPreview();
|
||||
|
||||
void drawInPlaylist(QPainter &p, const HistoryItem *parent, bool selected, bool over, int32 width) const;
|
||||
TextLinkPtr linkInPlaylist();
|
||||
|
||||
private:
|
||||
|
||||
DocumentData *data;
|
||||
@@ -1066,7 +1078,7 @@ public:
|
||||
const QString inHistoryText() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
int32 countHeight(const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
HistoryMedia *clone() const;
|
||||
|
||||
DocumentData *document() {
|
||||
@@ -1077,7 +1089,6 @@ public:
|
||||
void unregItem(HistoryItem *item);
|
||||
|
||||
void updateFrom(const MTPMessageMedia &media);
|
||||
bool updateStickerEmoji();
|
||||
|
||||
private:
|
||||
|
||||
@@ -1101,7 +1112,7 @@ public:
|
||||
const QString inDialogsText() const;
|
||||
const QString inHistoryText() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width) const;
|
||||
HistoryMedia *clone() const;
|
||||
|
||||
void updateFrom(const MTPMessageMedia &media);
|
||||
@@ -1131,7 +1142,7 @@ public:
|
||||
const QString inDialogsText() const;
|
||||
const QString inHistoryText() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
HistoryMedia *clone() const;
|
||||
|
||||
void regItem(HistoryItem *item);
|
||||
@@ -1224,7 +1235,7 @@ public:
|
||||
const QString inDialogsText() const;
|
||||
const QString inHistoryText() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
HistoryMedia *clone() const;
|
||||
|
||||
bool isImageLink() const {
|
||||
@@ -1266,8 +1277,8 @@ public:
|
||||
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
|
||||
bool hasPoint(int32 x, int32 y) const;
|
||||
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const;
|
||||
virtual void getStateFromMessageText(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const QRect &r) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
||||
virtual void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const;
|
||||
|
||||
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
|
||||
uint32 adjustSelection(uint16 from, uint16 to, TextSelectType type) const {
|
||||
@@ -1283,7 +1294,6 @@ public:
|
||||
_media->updateFrom(media);
|
||||
}
|
||||
}
|
||||
void updateStickerEmoji();
|
||||
|
||||
QString selectedText(uint32 selection) const;
|
||||
QString inDialogsText() const;
|
||||
@@ -1342,9 +1352,9 @@ public:
|
||||
void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const;
|
||||
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
|
||||
bool hasPoint(int32 x, int32 y) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const;
|
||||
void getStateFromMessageText(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const QRect &r) const;
|
||||
void getForwardedState(TextLinkPtr &lnk, bool &inText, int32 x, int32 w) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
||||
void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const;
|
||||
void getForwardedState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 w) const;
|
||||
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
|
||||
|
||||
QDateTime dateForwarded() const {
|
||||
@@ -1395,8 +1405,8 @@ public:
|
||||
void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const;
|
||||
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
|
||||
bool hasPoint(int32 x, int32 y) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const;
|
||||
void getStateFromMessageText(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const QRect &r) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
||||
void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const;
|
||||
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
|
||||
|
||||
UserData *replyTo() const {
|
||||
@@ -1436,7 +1446,7 @@ public:
|
||||
void draw(QPainter &p, uint32 selection) const;
|
||||
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
|
||||
bool hasPoint(int32 x, int32 y) const;
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
||||
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
|
||||
uint32 adjustSelection(uint16 from, uint16 to, TextSelectType type) const {
|
||||
return _text.adjustSelection(from, to, type);
|
||||
@@ -1477,9 +1487,9 @@ class HistoryDateMsg : public HistoryServiceMsg {
|
||||
public:
|
||||
|
||||
HistoryDateMsg(History *history, HistoryBlock *block, const QDate &date);
|
||||
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const {
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const {
|
||||
lnk = TextLinkPtr();
|
||||
inText = false;
|
||||
state = HistoryDefaultCursorState;
|
||||
}
|
||||
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
|
||||
symbol = 0xFFFF;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -81,6 +81,8 @@ public:
|
||||
|
||||
void updateBotInfo(bool recount = true);
|
||||
|
||||
bool wasSelectedText() const;
|
||||
|
||||
~HistoryList();
|
||||
|
||||
public slots:
|
||||
@@ -104,6 +106,7 @@ public slots:
|
||||
void onMenuDestroy(QObject *obj);
|
||||
void onTouchSelect();
|
||||
void onTouchScrollTimer();
|
||||
void onDragExec();
|
||||
|
||||
private:
|
||||
|
||||
@@ -115,7 +118,6 @@ private:
|
||||
HistoryItem *prevItem(HistoryItem *item);
|
||||
HistoryItem *nextItem(HistoryItem *item);
|
||||
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false);
|
||||
void applyDragSelection();
|
||||
|
||||
History *hist;
|
||||
|
||||
@@ -133,6 +135,9 @@ private:
|
||||
Qt::CursorShape _cursor;
|
||||
typedef QMap<HistoryItem*, uint32> SelectedItems;
|
||||
SelectedItems _selected;
|
||||
void applyDragSelection();
|
||||
void applyDragSelection(SelectedItems *toItems) const;
|
||||
|
||||
enum DragAction {
|
||||
NoDrag = 0x00,
|
||||
PrepareDrag = 0x01,
|
||||
@@ -144,6 +149,7 @@ private:
|
||||
TextSelectType _dragSelType;
|
||||
QPoint _dragStartPos, _dragPos;
|
||||
HistoryItem *_dragItem;
|
||||
HistoryCursorState _dragCursorState;
|
||||
uint16 _dragSymbol;
|
||||
bool _dragWasInactive;
|
||||
|
||||
@@ -154,6 +160,7 @@ private:
|
||||
|
||||
HistoryItem *_dragSelFrom, *_dragSelTo;
|
||||
bool _dragSelecting;
|
||||
bool _wasSelectedText; // was some text selected in current drag action
|
||||
|
||||
bool _touchScroll, _touchSelect, _touchInProgress;
|
||||
QPoint _touchStart, _touchPrevPos, _touchPos;
|
||||
@@ -409,6 +416,7 @@ public:
|
||||
void animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false);
|
||||
bool showStep(float64 ms);
|
||||
void animStop();
|
||||
void doneShow();
|
||||
|
||||
QPoint clampMousePosition(QPoint point);
|
||||
|
||||
@@ -460,6 +468,8 @@ public:
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
void updateBotKeyboard();
|
||||
|
||||
DragState getDragState(const QMimeData *d);
|
||||
|
||||
~HistoryWidget();
|
||||
|
||||
signals:
|
||||
@@ -502,10 +512,12 @@ public slots:
|
||||
|
||||
void onPhotoSelect();
|
||||
void onDocumentSelect();
|
||||
void onPhotoDrop(QDropEvent *e);
|
||||
void onDocumentDrop(QDropEvent *e);
|
||||
void onPhotoDrop(const QMimeData *data);
|
||||
void onDocumentDrop(const QMimeData *data);
|
||||
void onFilesDrop(const QMimeData *data);
|
||||
|
||||
void onKbToggle(bool manual = true);
|
||||
void onCmdStart();
|
||||
|
||||
void onPhotoReady();
|
||||
void onSendConfirmed();
|
||||
@@ -514,8 +526,10 @@ public slots:
|
||||
void showPeer(const PeerId &peer, MsgId msgId = 0, bool force = false, bool leaveActive = false);
|
||||
void clearLoadingAround();
|
||||
void activate();
|
||||
void onMentionHashtagOrBotCommandInsert(QString str);
|
||||
void onTextChange();
|
||||
|
||||
void onFieldTabbed();
|
||||
void onStickerSend(DocumentData *sticker);
|
||||
|
||||
void onVisibleChanged();
|
||||
@@ -541,6 +555,7 @@ public slots:
|
||||
void onDraftSave(bool delayed = false);
|
||||
|
||||
void updateStickers();
|
||||
void botCommandsChanged(UserData *user);
|
||||
|
||||
void onRecordError();
|
||||
void onRecordDone(QByteArray result, qint32 samples);
|
||||
@@ -591,7 +606,6 @@ private:
|
||||
void setFieldText(const QString &text);
|
||||
|
||||
QStringList getMediasFromMime(const QMimeData *d);
|
||||
DragState getDragState(const QMimeData *d);
|
||||
|
||||
void updateDragAreas();
|
||||
|
||||
@@ -616,9 +630,11 @@ private:
|
||||
MentionsDropdown _attachMention;
|
||||
|
||||
bool isBotStart() const;
|
||||
bool updateCmdStartShown();
|
||||
|
||||
FlatButton _send, _botStart;
|
||||
IconedButton _attachDocument, _attachPhoto, _attachEmoji, _kbShow, _kbHide;
|
||||
IconedButton _attachDocument, _attachPhoto, _attachEmoji, _kbShow, _kbHide, _cmdStart;
|
||||
bool _cmdStartShown;
|
||||
MessageField _field;
|
||||
Animation _recordAnim, _recordingAnim;
|
||||
bool _recording, _inRecord, _inField, _inReply;
|
||||
|
||||
@@ -26,6 +26,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace {
|
||||
class SignUpLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(SignUpLink)
|
||||
|
||||
public:
|
||||
|
||||
SignUpLink(IntroPhone *widget) : _widget(widget) {
|
||||
|
||||
@@ -71,28 +71,28 @@ void LangLoader::foundKeyValue(LangKey key) {
|
||||
}
|
||||
|
||||
QString Translator::translate(const char *context, const char *sourceText, const char *disambiguation, int n) const {
|
||||
if (QLatin1String("QMenuBar") == context) {
|
||||
if (QLatin1String("Services") == sourceText) return lang(lng_mac_menu_services);
|
||||
if (QLatin1String("Hide %1") == sourceText) return lng_mac_menu_hide_telegram(lt_telegram, qsl("%1"));
|
||||
if (QLatin1String("Hide Others") == sourceText) return lang(lng_mac_menu_hide_others);
|
||||
if (QLatin1String("Show All") == sourceText) return lang(lng_mac_menu_show_all);
|
||||
if (QLatin1String("Preferences...") == sourceText) return lang(lng_mac_menu_preferences);
|
||||
if (QLatin1String("Quit %1") == sourceText) return lng_mac_menu_quit_telegram(lt_telegram, qsl("%1"));
|
||||
if (QLatin1String("About %1") == sourceText) return lng_mac_menu_about_telegram(lt_telegram, qsl("%1"));
|
||||
if (qstr("QMenuBar") == context) {
|
||||
if (qstr("Services") == sourceText) return lang(lng_mac_menu_services);
|
||||
if (qstr("Hide %1") == sourceText) return lng_mac_menu_hide_telegram(lt_telegram, qsl("%1"));
|
||||
if (qstr("Hide Others") == sourceText) return lang(lng_mac_menu_hide_others);
|
||||
if (qstr("Show All") == sourceText) return lang(lng_mac_menu_show_all);
|
||||
if (qstr("Preferences...") == sourceText) return lang(lng_mac_menu_preferences);
|
||||
if (qstr("Quit %1") == sourceText) return lng_mac_menu_quit_telegram(lt_telegram, qsl("%1"));
|
||||
if (qstr("About %1") == sourceText) return lng_mac_menu_about_telegram(lt_telegram, qsl("%1"));
|
||||
return QString();
|
||||
}
|
||||
if (QLatin1String("QWidgetTextControl") == context || QLatin1String("QLineEdit") == context) {
|
||||
if (QLatin1String("&Undo") == sourceText) return lang((cPlatform() == dbipWindows) ? lng_wnd_menu_undo : ((cPlatform() == dbipMac) ? lng_mac_menu_undo : lng_linux_menu_undo));
|
||||
if (QLatin1String("&Redo") == sourceText) return lang((cPlatform() == dbipWindows) ? lng_wnd_menu_redo : ((cPlatform() == dbipMac) ? lng_mac_menu_redo : lng_linux_menu_redo));
|
||||
if (QLatin1String("Cu&t") == sourceText) return lang(lng_mac_menu_cut);
|
||||
if (QLatin1String("&Copy") == sourceText) return lang(lng_mac_menu_copy);
|
||||
if (QLatin1String("&Paste") == sourceText) return lang(lng_mac_menu_paste);
|
||||
if (QLatin1String("Delete") == sourceText) return lang(lng_mac_menu_delete);
|
||||
if (QLatin1String("Select All") == sourceText) return lang(lng_mac_menu_select_all);
|
||||
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("&Redo") == sourceText) return lang((cPlatform() == dbipWindows) ? lng_wnd_menu_redo : ((cPlatform() == dbipMac) ? lng_mac_menu_redo : lng_linux_menu_redo));
|
||||
if (qstr("Cu&t") == sourceText) return lang(lng_mac_menu_cut);
|
||||
if (qstr("&Copy") == sourceText) return lang(lng_mac_menu_copy);
|
||||
if (qstr("&Paste") == sourceText) return lang(lng_mac_menu_paste);
|
||||
if (qstr("Delete") == sourceText) return lang(lng_mac_menu_delete);
|
||||
if (qstr("Select All") == sourceText) return lang(lng_mac_menu_select_all);
|
||||
return QString();
|
||||
}
|
||||
if (QLatin1String("QUnicodeControlCharacterMenu") == context) {
|
||||
if (QLatin1String("Insert Unicode control character") == sourceText) return lang(lng_menu_insert_unicode);
|
||||
if (qstr("QUnicodeControlCharacterMenu") == context) {
|
||||
if (qstr("Insert Unicode control character") == sourceText) return lang(lng_menu_insert_unicode);
|
||||
return QString();
|
||||
}
|
||||
return QString();
|
||||
|
||||
@@ -166,11 +166,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_username_title" = "Benutzernamen ändern";
|
||||
"lng_username_about" = "Wähle einen (optionalen) öffentlichen \nBenutzernamen, wenn du von anderen \ngefunden werden willst, ohne, dass sie \ndeine Nummer kennen müssen.\n\nErlaubt sind a-z, 0-9 und Unterstriche. \nDie Mindestlänge beträgt 5 Zeichen.";
|
||||
"lng_username_invalid" = "Der Benutzername ist fehlerhaft.";
|
||||
"lng_username_occupied" = "Der Benutzername ist bereits belegt.";
|
||||
"lng_username_too_short" = "Der Benutzername ist zu kurz.";
|
||||
"lng_username_bad_symbols" = "Nur a-z, 0-9 und Unterstriche sind erlaubt.";
|
||||
"lng_username_available" = "Der Benutzername ist noch verfügbar.";
|
||||
"lng_username_invalid" = "Benutzername ungültig.";
|
||||
"lng_username_occupied" = "Benutzername ist bereits belegt.";
|
||||
"lng_username_too_short" = "Benutzername ist zu kurz.";
|
||||
"lng_username_bad_symbols" = "Ungültige Zeichen im Benutzernamen.";
|
||||
"lng_username_available" = "Benutzername ist verfügbar.";
|
||||
"lng_username_not_found" = "Kontakt @{user} konnte nicht gefunden werden.";
|
||||
|
||||
"lng_settings_section_contact_info" = "Kontaktprofil";
|
||||
@@ -301,13 +301,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_connection_type" = "Verbindungsart:";
|
||||
"lng_connection_auto_connecting" = "Standard (verbinden..)";
|
||||
"lng_connection_auto" = "Standard ({type} verwendet)";
|
||||
"lng_connection_http_proxy" = "HTTP mit Proxy";
|
||||
"lng_connection_tcp_proxy" = "TCP mit Proxy";
|
||||
"lng_connection_auto" = "Standard ({transport} verwendet)";
|
||||
"lng_connection_proxy_connecting" = "Verbinde über Proxy...";
|
||||
"lng_connection_proxy" = "{transport} mit Proxy";
|
||||
"lng_connection_header" = "Verbindungsart";
|
||||
"lng_connection_auto_rb" = "Auto (TCP wenn verfügbar oder HTTP)";
|
||||
"lng_connection_http_proxy_rb" = "HTTP mit benutzerdef. http-Proxy";
|
||||
"lng_connection_tcp_proxy_rb" = "TCP mit benutzerdef. socks5-Proxy";
|
||||
"lng_connection_try_ipv6" = "Über IPv6 verbinden";
|
||||
"lng_connection_host_ph" = "Hostname";
|
||||
"lng_connection_port_ph" = "Port";
|
||||
"lng_connection_user_ph" = "Benutzername";
|
||||
@@ -367,6 +368,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Dateiübersicht";
|
||||
"lng_profile_audios" = "{count:_not_used_|# Sprachnachricht|# Sprachnachrichten} »";
|
||||
"lng_profile_audios_header" = "Übersicht Sprachnachrichten";
|
||||
"lng_profile_audio_files_header" = "Wiedergabeliste";
|
||||
"lng_profile_show_all_types" = "Alle Filter anzeigen";
|
||||
"lng_profile_copy_phone" = "Telefonnummer kopieren";
|
||||
|
||||
@@ -572,7 +574,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_selected_delete_confirm" = "Löschen";
|
||||
|
||||
"lng_about_version" = "Version {version}";
|
||||
"lng_about_text" = "Telegram Desktop basiert auf [a href=\"https://core.telegram.org/mtproto\"]MTProto[/a] und\ndem [a href=\"https://core.telegram.org/api\"]Telegram API[/a], um Geschwindigkeit \nund Sicherheit zu gewährleisten.\n\nSoftware steht unter der [a href=\"https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\"]GNU GPL[/a] Version 3,\nQuelltext ist bei [a href=\"https://github.com/telegramdesktop/tdesktop\"]GitHub[/a] verfügbar.";
|
||||
"lng_about_text" = "Telegram Desktop basiert auf [a href=\"https://core.telegram.org/mtproto\"]MTProto[/a] und\nder [a href=\"https://core.telegram.org/api\"]Telegram API[/a], um Geschwindigkeit \nund Sicherheit zu gewährleisten.\n\nSoftware steht unter der [a href=\"https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\"]GNU GPL[/a] Version 3,\nQuelltext ist bei [a href=\"https://github.com/telegramdesktop/tdesktop\"]GitHub[/a] verfügbar.";
|
||||
"lng_about_done" = "Fertig";
|
||||
|
||||
"lng_search_found_results" = "{count:Keine Nachrichten|# Nachricht|# Nachrichten}";
|
||||
@@ -601,7 +603,7 @@ Copyright (c) 2014 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_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
||||
"lng_new_version_text" = "Diese neue Version enthält Unterstützung für die neue Bot API, welche für alle kostenlos verfügbar ist. Kannst du programmieren? Erstelle deine eigenen Bots für Spiele, Dienste oder Integrationen.\n\nMehr dazu unter {blog_link}";
|
||||
"lng_new_version_text" = "— In-App Medienwiedergabe optimiert\n— Fehlerbehebungen und kleinere Verbesserungen";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
||||
|
||||
|
||||
@@ -301,13 +301,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_connection_type" = "Tipo de conexión:";
|
||||
"lng_connection_auto_connecting" = "Por defecto (conectando...)";
|
||||
"lng_connection_auto" = "Por defecto ({type} en uso)";
|
||||
"lng_connection_http_proxy" = "HTTP con proxy";
|
||||
"lng_connection_tcp_proxy" = "TCP con proxy";
|
||||
"lng_connection_auto" = "Por defecto ({transport} en uso)";
|
||||
"lng_connection_proxy_connecting" = "Conectando a través de un proxy...";
|
||||
"lng_connection_proxy" = "{transport} con un proxy";
|
||||
"lng_connection_header" = "Tipo de conexión";
|
||||
"lng_connection_auto_rb" = "Automático (TCP si está disponible o HTTP)";
|
||||
"lng_connection_http_proxy_rb" = "HTTP con http-proxy personalizado";
|
||||
"lng_connection_tcp_proxy_rb" = "TCP con socks5-proxy personalizado";
|
||||
"lng_connection_try_ipv6" = "Intentar conectar a través de IPv6";
|
||||
"lng_connection_host_ph" = "Nombre del host";
|
||||
"lng_connection_port_ph" = "Puerto";
|
||||
"lng_connection_user_ph" = "Alias";
|
||||
@@ -362,11 +363,12 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_photos" = "{count:_not_used_|# foto|# fotos} »";
|
||||
"lng_profile_photos_header" = "Todas las fotos";
|
||||
"lng_profile_videos" = "{count:_not_used_|# vídeo|# vídeos} »";
|
||||
"lng_profile_videos_header" = "Todos los vídeos";
|
||||
"lng_profile_videos_header" = "Vídeos";
|
||||
"lng_profile_files" = "{count:_not_used_|# archivo|# archivos} »";
|
||||
"lng_profile_files_header" = "Todos los archivos";
|
||||
"lng_profile_files_header" = "Archivos";
|
||||
"lng_profile_audios" = "{count:_not_used_|# mensaje de voz|# mensajes de voz} »";
|
||||
"lng_profile_audios_header" = "Todos los mensajes de voz";
|
||||
"lng_profile_audios_header" = "Mensajes de voz";
|
||||
"lng_profile_audio_files_header" = "Lista de reproducción";
|
||||
"lng_profile_show_all_types" = "Mostrar todos los tipos";
|
||||
"lng_profile_copy_phone" = "Copiar número";
|
||||
|
||||
@@ -464,7 +466,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_from_you" = "Tú";
|
||||
"lng_bot_description" = "¿Qué puede hacer este bot?";
|
||||
|
||||
"lng_bot_start" = "Empezar";
|
||||
"lng_bot_start" = "Iniciar";
|
||||
"lng_bot_choose_group" = "Elegir grupo";
|
||||
"lng_bot_no_groups" = "No tienes grupos";
|
||||
"lng_bot_groups_not_found" = "No se encontraron grupos";
|
||||
@@ -601,7 +603,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop fue 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_text" = "Esta nueva versión incluye el soporte para bots, usando la nueva API para bots, gratis para todos. Si eres un ingeniero, crea tus propios bots para juegos, servicios o integraciones .\n\nConoce más en {blog_link}";
|
||||
"lng_new_version_text" = "— Reproducción de la multimedia dentro de la aplicación mejorada\n— Corrección de errores y otras mejoras menores";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
||||
|
||||
|
||||
@@ -166,11 +166,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_username_title" = "Cambia username";
|
||||
"lng_username_about" = "Puoi scegliere un username su Telegram.\nSe lo fai, le altre persone potranno trovarti\ntramite questo nome utente e contattarti \nsenza conoscere il tuo numero di telefono.\n\nPuoi usare a-z, 0-9 e underscore.\nLa lunghezza minima è di 5 caratteri.";
|
||||
"lng_username_invalid" = "Il nome non è valido.";
|
||||
"lng_username_occupied" = "Il nome è già occupato.";
|
||||
"lng_username_too_short" = "Il nome è troppo corto.";
|
||||
"lng_username_bad_symbols" = "Questo nome ha simboli errati.";
|
||||
"lng_username_available" = "Il nome è disponibile.";
|
||||
"lng_username_invalid" = "L'username non è valido.";
|
||||
"lng_username_occupied" = "L'username è già occupato.";
|
||||
"lng_username_too_short" = "L'username è troppo corto.";
|
||||
"lng_username_bad_symbols" = "Questo username ha simboli errati.";
|
||||
"lng_username_available" = "L'username è disponibile.";
|
||||
"lng_username_not_found" = "Utente @{user} non trovato.";
|
||||
|
||||
"lng_settings_section_contact_info" = "Informazioni di contatto";
|
||||
@@ -301,13 +301,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_connection_type" = "Tipo di connessione:";
|
||||
"lng_connection_auto_connecting" = "Default (connessione..)";
|
||||
"lng_connection_auto" = "Default ({type} in uso)";
|
||||
"lng_connection_http_proxy" = "HTTP con proxy";
|
||||
"lng_connection_tcp_proxy" = "TCP con proxy";
|
||||
"lng_connection_auto" = "Predefinito ({transport} in uso)";
|
||||
"lng_connection_proxy_connecting" = "Connessione tramite proxy..";
|
||||
"lng_connection_proxy" = "{transport} con proxy";
|
||||
"lng_connection_header" = "Tipo di connessione";
|
||||
"lng_connection_auto_rb" = "Auto (TCP se disponibile o HTTP)";
|
||||
"lng_connection_http_proxy_rb" = "HTTP con proxy-http personalizzato";
|
||||
"lng_connection_tcp_proxy_rb" = "TCP con proxy-socks5 personalizzato";
|
||||
"lng_connection_try_ipv6" = "Prova a connettere tramite IPv6";
|
||||
"lng_connection_host_ph" = "Hostname";
|
||||
"lng_connection_port_ph" = "Porta";
|
||||
"lng_connection_user_ph" = "Username";
|
||||
@@ -367,6 +368,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Panoramica file";
|
||||
"lng_profile_audios" = "{count:_not_used_|# nota vocale|# note vocali} »";
|
||||
"lng_profile_audios_header" = "Panoramica note vocali";
|
||||
"lng_profile_audio_files_header" = "Playlist";
|
||||
"lng_profile_show_all_types" = "Mostra tutti i tipi";
|
||||
"lng_profile_copy_phone" = "Copia numero di telefono";
|
||||
|
||||
@@ -601,7 +603,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli update è disponibile qui:\n{link}";
|
||||
"lng_new_version_minor" = "— Bug fix e altri miglioramenti minori";
|
||||
"lng_new_version_text" = "Questa nuova versione include il support per i bot usando la nuova API per i bot. Se sei un ingegnere, crea i tuoi bot per giochi, servizi o integrazioni. Scopri di più su {blog_link}";
|
||||
"lng_new_version_text" = "— Riproduzione dei media migliorata\n— Risoluzione di bug e miglioramenti minori";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_username_invalid" = "올바르지 않은 아이디입니다.";
|
||||
"lng_username_occupied" = "사용중인 아이디입니다.";
|
||||
"lng_username_too_short" = "아이디가 너무 짧습니다.";
|
||||
"lng_username_bad_symbols" = "올바르지 않은 아이디입니다.";
|
||||
"lng_username_bad_symbols" = "아이디에 올바르지 않은 문자가 있습니다.";
|
||||
"lng_username_available" = "사용 가능한 아이디입니다.";
|
||||
"lng_username_not_found" = "아이디 @{user}를 찾을 수 없습니다.";
|
||||
|
||||
@@ -301,13 +301,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_connection_type" = "연결 유형:";
|
||||
"lng_connection_auto_connecting" = "기본값 (연결중..)";
|
||||
"lng_connection_auto" = "기본값 ({type} 사용)";
|
||||
"lng_connection_http_proxy" = "HTTP 프록시";
|
||||
"lng_connection_tcp_proxy" = "TCP 프록시";
|
||||
"lng_connection_auto" = "기본값 ({transport} 사용)";
|
||||
"lng_connection_proxy_connecting" = "프록시 연결 중...";
|
||||
"lng_connection_proxy" = "{transport} 프록시 연결";
|
||||
"lng_connection_header" = "연결 유형";
|
||||
"lng_connection_auto_rb" = "자동 (사용 가능하다면 TCP 아니면 HTTP 사용)";
|
||||
"lng_connection_http_proxy_rb" = "HTTP (커스텀 HTTP 프록시)";
|
||||
"lng_connection_tcp_proxy_rb" = "TCP (커스텀 socks5-proxy)";
|
||||
"lng_connection_try_ipv6" = "IPv6로 연결 시도 중";
|
||||
"lng_connection_host_ph" = "호스트네임";
|
||||
"lng_connection_port_ph" = "포트";
|
||||
"lng_connection_user_ph" = "아이디";
|
||||
@@ -367,6 +368,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "파일 내역";
|
||||
"lng_profile_audios" = "{count:_not_used_|#개의 음성 메시지|#개의 음성 메시지} »";
|
||||
"lng_profile_audios_header" = "음성 메시지 내역";
|
||||
"lng_profile_audio_files_header" = "재생목록";
|
||||
"lng_profile_show_all_types" = "모든 유형 보기";
|
||||
"lng_profile_copy_phone" = "전화번호 복사";
|
||||
|
||||
@@ -601,7 +603,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
||||
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
||||
"lng_new_version_text" = "새로운 버전에서는 신규 봇 API를 무료로 공개합니다. 개발자라면 누구나 게임, 서비스나 통합 봇등 개발이 가능합니다. \n\n{blog_link}에서 자세한 사항을 알아보세요.";
|
||||
"lng_new_version_text" = "— 앱내 미디어 재생 기능 향상\n— 버그 수정 및 마이나 기능 향상";
|
||||
|
||||
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
||||
|
||||
|
||||
@@ -166,11 +166,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_username_title" = "Gebruikersnaam wijzigen";
|
||||
"lng_username_about" = "Je kunt hier je gebruikersnaam kiezen. \nHiermee kunnen anderen je vinden \nen contact met je opnemen zonder \nje telefoonnummer te weten.\n\na-z, 0-9 en underscore is toegestaan. \nDe minimale lengte is 5 tekens.";
|
||||
"lng_username_invalid" = "Deze naam is ongeldig.";
|
||||
"lng_username_occupied" = "Sorry, deze gebruikersnaam is al bezet.";
|
||||
"lng_username_too_short" = "Deze naam is te kort.";
|
||||
"lng_username_bad_symbols" = "Sorry, deze naam bevat ongeldige tekens.";
|
||||
"lng_username_available" = "Deze naam is beschikbaar.";
|
||||
"lng_username_invalid" = "Deze gebruikersnaam is ongeldig.";
|
||||
"lng_username_occupied" = "Deze gebruikersnaam is al bezet";
|
||||
"lng_username_too_short" = "Deze gebruikersnaam is te kort.";
|
||||
"lng_username_bad_symbols" = "Deze gebruikersnaam bevat ongeldige tekens.";
|
||||
"lng_username_available" = "Deze gebruikersnaam is beschikbaar.";
|
||||
"lng_username_not_found" = "Gebruiker @{user} niet gevonden.";
|
||||
|
||||
"lng_settings_section_contact_info" = "Contactgegevens";
|
||||
@@ -301,13 +301,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_connection_type" = "Verbindingstype:";
|
||||
"lng_connection_auto_connecting" = "Standaard (verbinden)";
|
||||
"lng_connection_auto" = "Standaard ({type} wordt gebruikt)";
|
||||
"lng_connection_http_proxy" = "HTTP met proxy";
|
||||
"lng_connection_tcp_proxy" = "TCP met proxy";
|
||||
"lng_connection_auto" = "Standaard ({transport} wordt gebruikt)";
|
||||
"lng_connection_proxy_connecting" = "Verbinden via proxy..";
|
||||
"lng_connection_proxy" = "{transport} met proxy";
|
||||
"lng_connection_header" = "Verbindingstype";
|
||||
"lng_connection_auto_rb" = "Auto (TCP indien beschikbaar of HTTP)";
|
||||
"lng_connection_http_proxy_rb" = "HTTP met aangepaste http-proxy";
|
||||
"lng_connection_tcp_proxy_rb" = "TCP met aangepaste socks5-proxy";
|
||||
"lng_connection_try_ipv6" = "Verbinden via IPV6";
|
||||
"lng_connection_host_ph" = "Hostnaam";
|
||||
"lng_connection_port_ph" = "Poort";
|
||||
"lng_connection_user_ph" = "Gebruikersnaam";
|
||||
@@ -367,6 +368,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Bestandsoverzicht";
|
||||
"lng_profile_audios" = "{count:_not_used_|# spraakbericht|# spraakberichten} »";
|
||||
"lng_profile_audios_header" = "Overzicht van spraakberichten";
|
||||
"lng_profile_audio_files_header" = "Afspeellijst";
|
||||
"lng_profile_show_all_types" = "Alles weergeven";
|
||||
"lng_profile_copy_phone" = "Telefoonnummer kopiëren";
|
||||
|
||||
@@ -601,7 +603,7 @@ Copyright (c) 2014 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_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
||||
"lng_new_version_text" = "Deze versie heeft ondersteuning voor de nieuwe bot-API, gratis voor iedereen. Handig met programmeren? Maak dan je eigen bots voor spelletjes, diensten en integraties. \n\nMeer weten? kijk op: {blog_link}";
|
||||
"lng_new_version_text" = "— Media afspelen binnen de app verbeterd\n— Probleemoplossing en kleine verbeteringen";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
||||
|
||||
|
||||
@@ -166,11 +166,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_username_title" = "Alterar nome de usuário";
|
||||
"lng_username_about" = "Você pode escolher um nome de usuário no Telegram.\nAssim, outras pessoas poderão te encontrar\npelo nome de usuário e entrar em contato\nsem precisar saber seu telefone.\n\nVocê pode usar a-z, 0-9 e underline.\nO tamanho mínimo é 5 caracteres.";
|
||||
"lng_username_invalid" = "Esse nome é inválido.";
|
||||
"lng_username_occupied" = "Esse nome já está ocupado.";
|
||||
"lng_username_too_short" = "Esse nome é muito curto.";
|
||||
"lng_username_bad_symbols" = "Esse nome contém símbolos incompatíveis.";
|
||||
"lng_username_available" = "Esse nome está disponível.";
|
||||
"lng_username_invalid" = "Nome de usuário inválido.";
|
||||
"lng_username_occupied" = "Nome de usuário ocupado.";
|
||||
"lng_username_too_short" = "Nome de usuário muito curto.";
|
||||
"lng_username_bad_symbols" = "Nome de usuário com símbolos incompatíveis.";
|
||||
"lng_username_available" = "Nome de usuário disponível.";
|
||||
"lng_username_not_found" = "Usuário @{user} não encontrado.";
|
||||
|
||||
"lng_settings_section_contact_info" = "Informação de contato";
|
||||
@@ -301,13 +301,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_connection_type" = "Tipo de conexão:";
|
||||
"lng_connection_auto_connecting" = "Padrão (conectando..)";
|
||||
"lng_connection_auto" = "Padrão ({type} usado)";
|
||||
"lng_connection_http_proxy" = "HTTP com proxy";
|
||||
"lng_connection_tcp_proxy" = "TCP com proxy";
|
||||
"lng_connection_auto" = "Padrão ({transport} usado)";
|
||||
"lng_connection_proxy_connecting" = "Conectando via proxy...";
|
||||
"lng_connection_proxy" = "{transport} com proxy";
|
||||
"lng_connection_header" = "Tipo de conexão";
|
||||
"lng_connection_auto_rb" = "Auto (TCP se disponível ou HTTP)";
|
||||
"lng_connection_http_proxy_rb" = "HTTP com http-proxy customizado";
|
||||
"lng_connection_tcp_proxy_rb" = "TCP com socks5-proxy customizado";
|
||||
"lng_connection_try_ipv6" = "Tentando conexão via IPv6";
|
||||
"lng_connection_host_ph" = "Nome do host";
|
||||
"lng_connection_port_ph" = "Porta";
|
||||
"lng_connection_user_ph" = "Nome de usuário";
|
||||
@@ -360,13 +361,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_shared_media" = "Mídia compartilhada";
|
||||
"lng_profile_no_media" = "Nenhuma mídia nessa conversa.";
|
||||
"lng_profile_photos" = "{count:_not_used_|# foto|# fotos} »";
|
||||
"lng_profile_photos_header" = "Visualização de fotos";
|
||||
"lng_profile_photos_header" = "Fotos";
|
||||
"lng_profile_videos" = "{count:_not_used_|# arquivo de vídeo|# arquivo de vídeos} »";
|
||||
"lng_profile_videos_header" = "Visualização de vídeos";
|
||||
"lng_profile_videos_header" = "Vídeos";
|
||||
"lng_profile_files" = "{count:_not_used_|# arquivo|# arquivos} »";
|
||||
"lng_profile_files_header" = "Visualização de arquivos";
|
||||
"lng_profile_files_header" = "Arquivos";
|
||||
"lng_profile_audios" = "{count:_not_used_|# mensagem de voz|# mensagens de voz} »";
|
||||
"lng_profile_audios_header" = "Visualização de mensagens de voz";
|
||||
"lng_profile_audios_header" = "Mensagens de voz";
|
||||
"lng_profile_audio_files_header" = "Reprodução";
|
||||
"lng_profile_show_all_types" = "Mostrar todos os tipos";
|
||||
"lng_profile_copy_phone" = "Copiar número de telefone";
|
||||
|
||||
@@ -601,7 +603,7 @@ Copyright (c) 2014 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_minor" = "— Resolução de bugs e outras menores melhorias";
|
||||
"lng_new_version_text" = "Essa nova versão inclui suporte para bots usando a nova API de bots. Se você for um engenheiro, crie seus próprios bots para jogos, serviços ou integrações.\n\nLeia mais em {blog_link}";
|
||||
"lng_new_version_text" = "— Reprodução de mídia no app melhorada\n— Resolução de bugs e menores melhorias";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "localimageloader.h"
|
||||
#include "gui/filedialog.h"
|
||||
#include "audio.h"
|
||||
#include <libexif/exif-data.h>
|
||||
|
||||
LocalImageLoaderPrivate::LocalImageLoaderPrivate(int32 currentUser, LocalImageLoader *loader, QThread *thread) : QObject(0)
|
||||
@@ -164,7 +165,40 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||
MTPDocument document(MTP_documentEmpty(MTP_long(0)));
|
||||
MTPAudio audio(MTP_audioEmpty(MTP_long(0)));
|
||||
|
||||
bool isSong = false;
|
||||
QByteArray jpeg;
|
||||
if (type == ToPrepareDocument) {
|
||||
if (mime == qstr("audio/mp3") || mime == qstr("audio/m4a") || mime == qstr("audio/aac") || mime == qstr("audio/ogg") ||
|
||||
filename.endsWith(qstr(".mp3"), Qt::CaseInsensitive) || filename.endsWith(qstr(".m4a"), Qt::CaseInsensitive) ||
|
||||
filename.endsWith(qstr(".aac"), Qt::CaseInsensitive) || filename.endsWith(qstr(".ogg"), Qt::CaseInsensitive)) {
|
||||
|
||||
QImage cover;
|
||||
QByteArray coverBytes, coverFormat;
|
||||
MTPDocumentAttribute audioAttribute = audioReadSongAttributes(file, data, cover, coverBytes, coverFormat);
|
||||
if (audioAttribute.type() == mtpc_documentAttributeAudio) {
|
||||
attributes.push_back(audioAttribute);
|
||||
isSong = true;
|
||||
if (!cover.isNull()) { // cover to thumb
|
||||
int32 cw = cover.width(), ch = cover.height();
|
||||
if (cw < 20 * ch && ch < 20 * cw) {
|
||||
QPixmap full = (cw > 90 || ch > 90) ? QPixmap::fromImage(cover.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(cover, Qt::ColorOnly);
|
||||
{
|
||||
QByteArray thumbFormat = "JPG";
|
||||
int32 thumbQuality = 87;
|
||||
|
||||
QBuffer jpegBuffer(&jpeg);
|
||||
full.save(&jpegBuffer, thumbFormat, thumbQuality);
|
||||
}
|
||||
|
||||
photoThumbs.insert('0', full);
|
||||
thumb = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0));
|
||||
|
||||
thumbId = MTP::nonce<uint64>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == ToPreparePhoto) {
|
||||
int32 w = img.width(), h = img.height();
|
||||
|
||||
@@ -189,7 +223,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||
photo = MTP_photo(MTP_long(id), MTP_long(0), MTP_int(user), MTP_int(unixtime()), MTP_geoPointEmpty(), MTP_vector<MTPPhotoSize>(photoSizes));
|
||||
|
||||
thumbId = id;
|
||||
} else if ((type == ToPrepareVideo || type == ToPrepareDocument) && !img.isNull()) {
|
||||
} else if ((type == ToPrepareVideo || type == ToPrepareDocument) && !img.isNull() && !isSong) {
|
||||
int32 w = img.width(), h = img.height();
|
||||
QByteArray thumbFormat = "JPG";
|
||||
int32 thumbQuality = 87;
|
||||
|
||||
@@ -517,6 +517,8 @@ namespace {
|
||||
typedef QPair<MediaKey, FileLocation> FileLocationPair;
|
||||
typedef QMap<QString, FileLocationPair> FileLocationPairs;
|
||||
FileLocationPairs _fileLocationPairs;
|
||||
typedef QMap<MediaKey, MediaKey> FileLocationAliases;
|
||||
FileLocationAliases _fileLocationAliases;
|
||||
FileKey _locationsKey = 0;
|
||||
|
||||
FileKey _recentStickersKeyOld = 0, _stickersKey = 0;
|
||||
@@ -566,14 +568,28 @@ namespace {
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
quint32 size = 0;
|
||||
for (FileLocations::const_iterator i = _fileLocations.cbegin(); i != _fileLocations.cend(); ++i) {
|
||||
for (FileLocations::const_iterator i = _fileLocations.cbegin(), e = _fileLocations.cend(); i != e; ++i) {
|
||||
// location + type + namelen + name + date + size
|
||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(i.value().name) + _dateTimeSize() + sizeof(quint32);
|
||||
}
|
||||
//end mark
|
||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(QString()) + _dateTimeSize() + sizeof(quint32);
|
||||
size += sizeof(quint32); // aliases count
|
||||
for (FileLocationAliases::const_iterator i = _fileLocationAliases.cbegin(), e = _fileLocationAliases.cend(); i != e; ++i) {
|
||||
// alias + location
|
||||
size += sizeof(quint64) * 2 + sizeof(quint64) * 2;
|
||||
}
|
||||
|
||||
EncryptedDescriptor data(size);
|
||||
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(0) << quint64(0) << quint32(0) << QString() << QDateTime::currentDateTime() << quint32(0);
|
||||
data.stream << quint32(_fileLocationAliases.size());
|
||||
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);
|
||||
}
|
||||
|
||||
FileWriteDescriptor file(_locationsKey);
|
||||
file.writeEncrypted(data);
|
||||
}
|
||||
@@ -588,12 +604,18 @@ namespace {
|
||||
return;
|
||||
}
|
||||
|
||||
bool endMarkFound = false;
|
||||
while (!locations.stream.atEnd()) {
|
||||
quint64 first, second;
|
||||
FileLocation loc;
|
||||
quint32 type;
|
||||
locations.stream >> first >> second >> type >> loc.name >> loc.modified >> loc.size;
|
||||
|
||||
if (!first && !second && !type && loc.name.isEmpty() && !loc.size) { // end mark
|
||||
endMarkFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
MediaKey key(first, second);
|
||||
loc.type = StorageFileType(type);
|
||||
|
||||
@@ -604,6 +626,16 @@ namespace {
|
||||
_writeLocations();
|
||||
}
|
||||
}
|
||||
|
||||
if (endMarkFound) {
|
||||
quint32 cnt;
|
||||
locations.stream >> cnt;
|
||||
for (quint32 i = 0; i < cnt; ++i) {
|
||||
quint64 kfirst, ksecond, vfirst, vsecond;
|
||||
locations.stream >> kfirst >> ksecond >> vfirst >> vsecond;
|
||||
_fileLocationAliases.insert(MediaKey(kfirst, ksecond), MediaKey(vfirst, vsecond));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mtpDcOptions *_dcOpts = 0;
|
||||
@@ -736,6 +768,14 @@ namespace {
|
||||
};
|
||||
} break;
|
||||
|
||||
case dbiTryIPv6: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetTryIPv6(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiSeenTrayTooltip: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
@@ -996,6 +1036,14 @@ namespace {
|
||||
cSetDialogLastPath(path);
|
||||
} break;
|
||||
|
||||
case dbiSongVolume: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetSongVolume(snap(v / 1e6, 0., 1.));
|
||||
} break;
|
||||
|
||||
default:
|
||||
LOG(("App Error: unknown blockId in _readSetting: %1").arg(blockId));
|
||||
return false;
|
||||
@@ -1217,7 +1265,7 @@ namespace {
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
|
||||
uint32 size = 11 * (sizeof(quint32) + sizeof(qint32));
|
||||
uint32 size = 12 * (sizeof(quint32) + sizeof(qint32));
|
||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
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));
|
||||
@@ -1238,6 +1286,7 @@ namespace {
|
||||
data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage());
|
||||
data.stream << quint32(dbiEmojiTab) << qint32(cEmojiTab());
|
||||
data.stream << quint32(dbiDialogLastPath) << cDialogLastPath();
|
||||
data.stream << quint32(dbiSongVolume) << qint32(qRound(cSongVolume() * 1e6));
|
||||
|
||||
{
|
||||
RecentEmojisPreload v(cRecentEmojisPreload());
|
||||
@@ -1789,7 +1838,7 @@ namespace Local {
|
||||
cSetDcOptions(dcOpts);
|
||||
}
|
||||
|
||||
quint32 size = 10 * (sizeof(quint32) + sizeof(qint32));
|
||||
quint32 size = 11 * (sizeof(quint32) + sizeof(qint32));
|
||||
for (mtpDcOptions::const_iterator i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) {
|
||||
size += sizeof(quint32) + sizeof(quint32) + sizeof(quint32);
|
||||
size += sizeof(quint32) + _stringSize(QString::fromUtf8(i->ip.data(), i->ip.size()));
|
||||
@@ -1827,6 +1876,7 @@ namespace Local {
|
||||
const ConnectionProxy &proxy(cConnectionProxy());
|
||||
data.stream << proxy.host << qint32(proxy.port) << proxy.user << proxy.password;
|
||||
}
|
||||
data.stream << quint32(dbiTryIPv6) << qint32(cTryIPv6());
|
||||
|
||||
TWindowPos pos(cWindowPos());
|
||||
data.stream << quint32(dbiWindowPosition) << qint32(pos.x) << qint32(pos.y) << qint32(pos.w) << qint32(pos.h) << qint32(pos.moncrc) << qint32(pos.maximized);
|
||||
@@ -1989,12 +2039,21 @@ namespace Local {
|
||||
return (_draftsPositionsMap.constFind(peer) != _draftsPositionsMap.cend());
|
||||
}
|
||||
|
||||
void writeFileLocation(const MediaKey &location, const FileLocation &local) {
|
||||
void writeFileLocation(MediaKey location, const FileLocation &local) {
|
||||
if (local.name.isEmpty()) return;
|
||||
|
||||
FileLocationAliases::const_iterator aliasIt = _fileLocationAliases.constFind(location);
|
||||
if (aliasIt != _fileLocationAliases.cend()) {
|
||||
location = aliasIt.value();
|
||||
}
|
||||
|
||||
FileLocationPairs::iterator i = _fileLocationPairs.find(local.name);
|
||||
if (i != _fileLocationPairs.cend()) {
|
||||
if (i.value().second == local) {
|
||||
if (i.value().first != location) {
|
||||
_fileLocationAliases.insert(location, i.value().first);
|
||||
_writeLocations(WriteMapFast);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (i.value().first != location) {
|
||||
@@ -2012,7 +2071,12 @@ namespace Local {
|
||||
_writeLocations(WriteMapFast);
|
||||
}
|
||||
|
||||
FileLocation readFileLocation(const MediaKey &location, bool check) {
|
||||
FileLocation readFileLocation(MediaKey location, bool check) {
|
||||
FileLocationAliases::const_iterator aliasIt = _fileLocationAliases.constFind(location);
|
||||
if (aliasIt != _fileLocationAliases.cend()) {
|
||||
location = aliasIt.value();
|
||||
}
|
||||
|
||||
FileLocations::iterator i = _fileLocations.find(location);
|
||||
for (FileLocations::iterator i = _fileLocations.find(location); (i != _fileLocations.end()) && (i.key() == location);) {
|
||||
if (check) {
|
||||
@@ -2231,13 +2295,21 @@ namespace Local {
|
||||
|
||||
void _writeStickerSet(QDataStream &stream, uint64 setId) {
|
||||
StickerSets::const_iterator it = cStickerSets().constFind(setId);
|
||||
if (it == cStickerSets().cend() || it->stickers.isEmpty()) return;
|
||||
if (it == cStickerSets().cend()) return;
|
||||
|
||||
stream << quint64(it->id) << quint64(it->access) << it->title << it->shortName << quint32(it->stickers.size());
|
||||
bool notLoaded = (it->flags & MTPDstickerSet_flag_NOT_LOADED);
|
||||
if (notLoaded) {
|
||||
stream << quint64(it->id) << quint64(it->access) << it->title << it->shortName << qint32(-it->count) << qint32(it->hash) << qint32(it->flags);
|
||||
return;
|
||||
} else {
|
||||
if (it->stickers.isEmpty()) return;
|
||||
}
|
||||
|
||||
stream << quint64(it->id) << quint64(it->access) << it->title << it->shortName << qint32(it->stickers.size()) << qint32(it->hash) << qint32(it->flags);
|
||||
for (StickerPack::const_iterator j = it->stickers.cbegin(), e = it->stickers.cend(); j != e; ++j) {
|
||||
DocumentData *doc = *j;
|
||||
stream << quint64(doc->id) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type) << doc->sticker->alt;
|
||||
switch (doc->sticker->set.type()) {
|
||||
stream << quint64(doc->id) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type) << doc->sticker()->alt;
|
||||
switch (doc->sticker()->set.type()) {
|
||||
case mtpc_inputStickerSetID: {
|
||||
stream << qint32(StickerSetTypeID);
|
||||
} break;
|
||||
@@ -2249,7 +2321,7 @@ namespace Local {
|
||||
stream << qint32(StickerSetTypeEmpty);
|
||||
} break;
|
||||
}
|
||||
const StorageImageLocation &loc(doc->sticker->loc);
|
||||
const StorageImageLocation &loc(doc->sticker()->loc);
|
||||
stream << qint32(loc.width) << qint32(loc.height) << qint32(loc.dc) << quint64(loc.volume) << qint32(loc.local) << quint64(loc.secret);
|
||||
}
|
||||
}
|
||||
@@ -2266,30 +2338,39 @@ namespace Local {
|
||||
}
|
||||
_writeMap();
|
||||
} else {
|
||||
int32 setsCount = 0;
|
||||
quint32 size = sizeof(quint32) + _bytearraySize(cStickersHash());
|
||||
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) {
|
||||
bool notLoaded = (i->flags & MTPDstickerSet_flag_NOT_LOADED);
|
||||
if (notLoaded) {
|
||||
if (!(i->flags & MTPDstickerSet_flag_disabled)) { // waiting to receive
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (i->stickers.isEmpty()) continue;
|
||||
}
|
||||
|
||||
// id + access + title + shortName + stickersCount + hash + flags
|
||||
size += sizeof(quint64) * 2 + _stringSize(i->title) + _stringSize(i->shortName) + sizeof(quint32) + sizeof(qint32) * 2;
|
||||
for (StickerPack::const_iterator j = i->stickers.cbegin(), e = i->stickers.cend(); j != e; ++j) {
|
||||
DocumentData *doc = *j;
|
||||
|
||||
// id + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + alt + type-of-set
|
||||
size += sizeof(quint64) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(doc->sticker()->alt) + sizeof(qint32);
|
||||
|
||||
// thumb-width + thumb-height + thumb-dc + thumb-volume + thumb-local + thumb-secret
|
||||
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint64) + sizeof(qint32) + sizeof(quint64);
|
||||
}
|
||||
++setsCount;
|
||||
}
|
||||
|
||||
if (!_stickersKey) {
|
||||
_stickersKey = genKey();
|
||||
_mapChanged = true;
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
quint32 size = sizeof(quint32) + _bytearraySize(cStickersHash());
|
||||
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) {
|
||||
if (i->stickers.isEmpty()) continue;
|
||||
|
||||
// id + access + title + shortName + stickersCount
|
||||
size += sizeof(quint64) * 2 + _stringSize(i->title) + _stringSize(i->shortName) + sizeof(quint32);
|
||||
for (StickerPack::const_iterator j = i->stickers.cbegin(), e = i->stickers.cend(); j != e; ++j) {
|
||||
DocumentData *doc = *j;
|
||||
|
||||
// id + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + alt + type-of-set
|
||||
size += sizeof(quint64) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(doc->sticker->alt) + sizeof(qint32);
|
||||
|
||||
// thumb-width + thumb-height + thumb-dc + thumb-volume + thumb-local + thumb-secret
|
||||
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint64) + sizeof(qint32) + sizeof(quint64);
|
||||
}
|
||||
}
|
||||
EncryptedDescriptor data(size);
|
||||
data.stream << quint32(cStickerSets().size()) << cStickersHash();
|
||||
_writeStickerSet(data.stream, DefaultStickerSetId);
|
||||
data.stream << quint32(setsCount) << cStickersHash();
|
||||
_writeStickerSet(data.stream, CustomStickerSetId);
|
||||
for (StickerSetsOrder::const_iterator i = cStickerSetsOrder().cbegin(), e = cStickerSetsOrder().cend(); i != e; ++i) {
|
||||
_writeStickerSet(data.stream, *i);
|
||||
@@ -2312,15 +2393,17 @@ namespace Local {
|
||||
|
||||
StickerSets &sets(cRefStickerSets());
|
||||
sets.clear();
|
||||
cSetStickerSetsOrder(StickerSetsOrder());
|
||||
|
||||
StickerSetsOrder &order(cRefStickerSetsOrder());
|
||||
order.clear();
|
||||
|
||||
RecentStickerPack &recent(cRefRecentStickers());
|
||||
recent.clear();
|
||||
|
||||
cSetStickersHash(QByteArray());
|
||||
|
||||
StickerSet &def(sets.insert(DefaultStickerSetId, StickerSet(DefaultStickerSetId, 0, lang(lng_stickers_default_set), QString())).value());
|
||||
StickerSet &custom(sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString())).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());
|
||||
|
||||
QMap<uint64, bool> read;
|
||||
while (!stickers.stream.atEnd()) {
|
||||
@@ -2347,16 +2430,22 @@ namespace Local {
|
||||
}
|
||||
|
||||
DocumentData *doc = App::documentSet(id, 0, access, date, attributes, mime, ImagePtr(), dc, size, StorageImageLocation());
|
||||
if (!doc->sticker) continue;
|
||||
if (!doc->sticker()) continue;
|
||||
|
||||
if (value > 0) {
|
||||
def.stickers.push_back(doc);
|
||||
++def.count;
|
||||
} else {
|
||||
custom.stickers.push_back(doc);
|
||||
++custom.count;
|
||||
}
|
||||
if (recent.size() < StickerPanPerRow * StickerPanRowsPerPage && qAbs(value) > 1) recent.push_back(qMakePair(doc, qAbs(value)));
|
||||
}
|
||||
if (def.stickers.isEmpty()) sets.remove(DefaultStickerSetId);
|
||||
if (def.stickers.isEmpty()) {
|
||||
sets.remove(DefaultStickerSetId);
|
||||
} else {
|
||||
order.push_front(DefaultStickerSetId);
|
||||
}
|
||||
if (custom.stickers.isEmpty()) sets.remove(CustomStickerSetId);
|
||||
|
||||
writeStickers();
|
||||
@@ -2396,11 +2485,18 @@ namespace Local {
|
||||
for (uint32 i = 0; i < cnt; ++i) {
|
||||
quint64 setId = 0, setAccess = 0;
|
||||
QString setTitle, setShortName;
|
||||
quint32 scnt = 0;
|
||||
qint32 scnt = 0;
|
||||
stickers.stream >> setId >> setAccess >> setTitle >> setShortName >> scnt;
|
||||
|
||||
qint32 setHash = 0, setFlags = 0;
|
||||
if (stickers.version > 8033) {
|
||||
stickers.stream >> setHash >> setFlags;
|
||||
}
|
||||
|
||||
if (setId == DefaultStickerSetId) {
|
||||
setTitle = lang(lng_stickers_default_set);
|
||||
setFlags |= MTPDstickerSet_flag_official;
|
||||
order.push_front(setId);
|
||||
} else if (setId == CustomStickerSetId) {
|
||||
setTitle = lang(lng_custom_stickers);
|
||||
} else if (setId) {
|
||||
@@ -2408,11 +2504,16 @@ namespace Local {
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
StickerSet &set(sets.insert(setId, StickerSet(setId, setAccess, setTitle, setShortName)).value());
|
||||
StickerSet &set(sets.insert(setId, StickerSet(setId, setAccess, setTitle, setShortName, 0, setHash, setFlags)).value());
|
||||
if (scnt < 0) { // disabled not loaded set
|
||||
set.count = -scnt;
|
||||
continue;
|
||||
}
|
||||
|
||||
set.stickers.reserve(scnt);
|
||||
|
||||
QMap<uint64, bool> read;
|
||||
for (uint32 j = 0; j < scnt; ++j) {
|
||||
for (int32 j = 0; j < scnt; ++j) {
|
||||
quint64 id, access;
|
||||
QString name, mime, alt;
|
||||
qint32 date, dc, size, width, height, type, typeOfSet;
|
||||
@@ -2453,9 +2554,10 @@ namespace Local {
|
||||
|
||||
StorageImageLocation thumb(thumbWidth, thumbHeight, thumbDc, thumbVolume, thumbLocal, thumbSecret);
|
||||
DocumentData *doc = App::documentSet(id, 0, access, date, attributes, mime, thumb.dc ? ImagePtr(thumb) : ImagePtr(), dc, size, thumb);
|
||||
if (!doc->sticker) continue;
|
||||
if (!doc->sticker()) continue;
|
||||
|
||||
set.stickers.push_back(doc);
|
||||
++set.count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2771,7 +2873,7 @@ namespace Local {
|
||||
if (!QDir(di.filePath()).removeRecursively()) result = false;
|
||||
} else {
|
||||
QString path = di.filePath();
|
||||
if (!path.endsWith(QLatin1String("map0")) && !path.endsWith(QLatin1String("map1"))) {
|
||||
if (!path.endsWith(qstr("map0")) && !path.endsWith(qstr("map1"))) {
|
||||
if (!QFile::remove(di.filePath())) result = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ namespace Local {
|
||||
MessageCursor readDraftPositions(const PeerId &peer);
|
||||
bool hasDraftPositions(const PeerId &peer);
|
||||
|
||||
void writeFileLocation(const StorageKey &location, const FileLocation &local);
|
||||
FileLocation readFileLocation(const StorageKey &location, bool check = true);
|
||||
void writeFileLocation(MediaKey location, const FileLocation &local);
|
||||
FileLocation readFileLocation(MediaKey location, bool check = true);
|
||||
|
||||
void writeImage(const StorageKey &location, const ImagePtr &img);
|
||||
void writeImage(const StorageKey &location, const StorageImageSaved &jpeg, bool overwrite = true);
|
||||
|
||||
@@ -277,7 +277,7 @@ void TopBarWidget::showAll() {
|
||||
resizeEvent(0);
|
||||
return;
|
||||
}
|
||||
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
|
||||
PeerData *p = App::main() ? App::main()->profilePeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0;
|
||||
if (p && (p->chat || p->asUser()->contact >= 0)) {
|
||||
if (p->chat) {
|
||||
if (p->asChat()->forbidden) {
|
||||
@@ -324,7 +324,7 @@ void TopBarWidget::showAll() {
|
||||
_mediaType.hide();
|
||||
}
|
||||
}
|
||||
if (App::main() && App::main()->historyPeer() && !p && _clearSelection.isHidden() && !cWideMode()) {
|
||||
if (App::main() && App::main()->historyPeer() && !o && !p && _clearSelection.isHidden() && !cWideMode()) {
|
||||
_info.show();
|
||||
} else {
|
||||
_info.hide();
|
||||
@@ -350,9 +350,12 @@ MainWidget *TopBarWidget::main() {
|
||||
return static_cast<MainWidget*>(parentWidget());
|
||||
}
|
||||
|
||||
MainWidget::MainWidget(Window *window) : QWidget(window), _started(0), failedObjId(0), _toForwardNameVersion(0), _dialogsWidth(st::dlgMinWidth),
|
||||
dialogs(this), history(this), profile(0), overview(0), _topBar(this), _forwardConfirm(0), hider(0), _mediaType(this), _mediaTypeMask(0),
|
||||
updGoodPts(0), updLastPts(0), updPtsCount(0), updDate(0), updQts(-1), updSeq(0), updInited(false), updSkipPtsUpdateLevel(0), _onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false),
|
||||
MainWidget::MainWidget(Window *window) : QWidget(window),
|
||||
_started(0), failedObjId(0), _toForwardNameVersion(0), _dialogsWidth(st::dlgMinWidth),
|
||||
dialogs(this), history(this), profile(0), overview(0), _player(this), _topBar(this),
|
||||
_forwardConfirm(0), hider(0), _playerHeight(0), _contentScrollAddToY(0), _mediaType(this), _mediaTypeMask(0),
|
||||
updGoodPts(0), updLastPts(0), updPtsCount(0), updDate(0), updQts(-1), updSeq(0), updInited(false), updSkipPtsUpdateLevel(0),
|
||||
_onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false),
|
||||
_failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _background(0), _api(new ApiWrap(this)) {
|
||||
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
|
||||
|
||||
@@ -369,14 +372,17 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
|
||||
connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||
connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||
connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(getDifferenceForce()));
|
||||
connect(_api, SIGNAL(fullPeerUpdated(PeerData*)), this, SIGNAL(peerUpdated(PeerData*)));
|
||||
connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*)));
|
||||
connect(&_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick()));
|
||||
connect(&history, SIGNAL(peerShown(PeerData*)), this, SLOT(onPeerShown(PeerData*)));
|
||||
connect(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings()));
|
||||
connect(this, SIGNAL(showPeerAsync(quint64,qint32,bool,bool)), this, SLOT(showPeer(quint64,qint32,bool,bool)), Qt::QueuedConnection);
|
||||
if (audioPlayer()) {
|
||||
connect(audioPlayer(), SIGNAL(updated(AudioData*)), this, SLOT(audioPlayProgress(AudioData*)));
|
||||
connect(audioPlayer(), SIGNAL(stopped(AudioData*)), this, SLOT(audioPlayProgress(AudioData*)));
|
||||
connect(audioPlayer(), SIGNAL(updated(const AudioMsgId&)), this, SLOT(audioPlayProgress(const AudioMsgId&)));
|
||||
connect(audioPlayer(), SIGNAL(stopped(const AudioMsgId&)), this, SLOT(audioPlayProgress(const AudioMsgId&)));
|
||||
connect(audioPlayer(), SIGNAL(updated(const SongMsgId&)), this, SLOT(documentPlayProgress(const SongMsgId&)));
|
||||
connect(audioPlayer(), SIGNAL(stopped(const SongMsgId&)), this, SLOT(documentPlayProgress(const SongMsgId&)));
|
||||
}
|
||||
connect(&_updateMutedTimer, SIGNAL(timeout()), this, SLOT(onUpdateMuted()));
|
||||
|
||||
@@ -394,7 +400,10 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
|
||||
App::wnd()->getTitle()->updateBackButton();
|
||||
_topBar.hide();
|
||||
|
||||
_player.hide();
|
||||
|
||||
_topBar.raise();
|
||||
_player.raise();
|
||||
dialogs.raise();
|
||||
_mediaType.raise();
|
||||
|
||||
@@ -409,17 +418,27 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
|
||||
_api->init();
|
||||
}
|
||||
|
||||
void MainWidget::onForward(const PeerId &peer, bool forwardSelected) {
|
||||
void MainWidget::onForward(const PeerId &peer, ForwardWhatMessages what) {
|
||||
history.cancelReply();
|
||||
_toForward.clear();
|
||||
if (forwardSelected) {
|
||||
if (what == ForwardSelectedMessages) {
|
||||
if (overview) {
|
||||
overview->fillSelectedItems(_toForward, false);
|
||||
} else {
|
||||
history.fillSelectedItems(_toForward, false);
|
||||
}
|
||||
} else if (App::contextItem() && dynamic_cast<HistoryMessage*>(App::contextItem()) && App::contextItem()->id > 0) {
|
||||
_toForward.insert(App::contextItem()->id, App::contextItem());
|
||||
} else {
|
||||
HistoryItem *item = 0;
|
||||
if (what == ForwardContextMessage) {
|
||||
item = App::contextItem();
|
||||
} else if (what == ForwardPressedMessage) {
|
||||
item = App::pressedItem();
|
||||
} else if (what == ForwardPressedLinkMessage) {
|
||||
item = App::pressedLinkItem();
|
||||
}
|
||||
if (dynamic_cast<HistoryMessage*>(item) && item->id > 0) {
|
||||
_toForward.insert(item->id, item);
|
||||
}
|
||||
}
|
||||
updateForwardingTexts();
|
||||
showPeer(peer, 0, false, true);
|
||||
@@ -559,6 +578,10 @@ void MainWidget::updateStickers() {
|
||||
history.updateStickers();
|
||||
}
|
||||
|
||||
void MainWidget::botCommandsChanged(UserData *bot) {
|
||||
history.botCommandsChanged(bot);
|
||||
}
|
||||
|
||||
void MainWidget::onUpdateMuted() {
|
||||
App::updateMuted();
|
||||
}
|
||||
@@ -571,6 +594,19 @@ void MainWidget::onSendPaths(const PeerId &peer) {
|
||||
history.onSendPaths(peer);
|
||||
}
|
||||
|
||||
void MainWidget::onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data) {
|
||||
if (data->hasFormat(qsl("application/x-td-forward-selected"))) {
|
||||
onForward(peer, ForwardSelectedMessages);
|
||||
} else if (data->hasFormat(qsl("application/x-td-forward-pressed-link"))) {
|
||||
onForward(peer, ForwardPressedLinkMessage);
|
||||
} else if (data->hasFormat(qsl("application/x-td-forward-pressed"))) {
|
||||
onForward(peer, ForwardPressedMessage);
|
||||
} else {
|
||||
showPeer(peer, 0, false, true);
|
||||
history.onFilesDrop(data);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::noHider(HistoryHider *destroyed) {
|
||||
if (hider == destroyed) {
|
||||
hider = 0;
|
||||
@@ -587,7 +623,7 @@ void MainWidget::noHider(HistoryHider *destroyed) {
|
||||
onPeerShown(history.peer());
|
||||
if (profile || overview || (history.peer() && history.peer()->id)) {
|
||||
dialogs.enableShadow(false);
|
||||
QPixmap animCache = myGrab(this, QRect(0, st::topBarHeight, _dialogsWidth, height() - st::topBarHeight)),
|
||||
QPixmap animCache = myGrab(this, QRect(0, _playerHeight + st::topBarHeight, _dialogsWidth, height() - _playerHeight - st::topBarHeight)),
|
||||
animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight));
|
||||
dialogs.enableShadow();
|
||||
_topBar.enableShadow();
|
||||
@@ -616,15 +652,16 @@ void MainWidget::hiderLayer(HistoryHider *h) {
|
||||
|
||||
hider = h;
|
||||
connect(hider, SIGNAL(forwarded()), &dialogs, SLOT(onCancelSearch()));
|
||||
dialogsToUp();
|
||||
if (cWideMode()) {
|
||||
hider->show();
|
||||
resizeEvent(0);
|
||||
dialogs.activate();
|
||||
} else {
|
||||
dialogsToUp();
|
||||
|
||||
hider->hide();
|
||||
dialogs.enableShadow(false);
|
||||
QPixmap animCache = myGrab(this, QRect(0, 0, _dialogsWidth, height()));
|
||||
QPixmap animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight));
|
||||
dialogs.enableShadow();
|
||||
_topBar.enableShadow();
|
||||
|
||||
@@ -694,6 +731,10 @@ void MainWidget::dialogsActivate() {
|
||||
dialogs.activate();
|
||||
}
|
||||
|
||||
DragState MainWidget::getDragState(const QMimeData *mime) {
|
||||
return history.getDragState(mime);
|
||||
}
|
||||
|
||||
bool MainWidget::leaveChatFailed(PeerData *peer, const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
@@ -735,14 +776,16 @@ void MainWidget::deleteMessages(const QVector<MTPint> &ids) {
|
||||
|
||||
void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result) {
|
||||
const MTPDcontacts_link &d(result.c_contacts_link());
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
||||
App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link);
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
||||
App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link, false);
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
void MainWidget::deleteHistoryAndContact(UserData *user, const MTPcontacts_Link &result) {
|
||||
const MTPDcontacts_link &d(result.c_contacts_link());
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
||||
App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link);
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
||||
App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link, false);
|
||||
App::emitPeerUpdated();
|
||||
|
||||
if ((profile && profile->peer() == user) || (overview && overview->peer() == user) || _stack.contains(user) || history.peer() == user) {
|
||||
showPeer(0);
|
||||
@@ -806,13 +849,13 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
|
||||
const QVector<MTPMessage> *v = 0;
|
||||
if (result.type() == mtpc_messages_messages) {
|
||||
const MTPDmessages_messages &d(result.c_messages_messages());
|
||||
App::feedChats(d.vchats);
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
v = &d.vmessages.c_vector().v;
|
||||
} else if (result.type() == mtpc_messages_messagesSlice) {
|
||||
const MTPDmessages_messagesSlice &d(result.c_messages_messagesSlice());
|
||||
App::feedChats(d.vchats);
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
v = &d.vmessages.c_vector().v;
|
||||
}
|
||||
if (!v) return;
|
||||
@@ -1105,13 +1148,14 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r
|
||||
}
|
||||
}
|
||||
|
||||
mediaOverviewUpdated(peer);
|
||||
mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
|
||||
void MainWidget::mediaOverviewUpdated(PeerData *peer) {
|
||||
if (profile) profile->mediaOverviewUpdated(peer);
|
||||
void MainWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
if (profile) profile->mediaOverviewUpdated(peer, type);
|
||||
if (!_player.isHidden()) _player.mediaOverviewUpdated(peer, type);
|
||||
if (overview && overview->peer() == peer) {
|
||||
overview->mediaOverviewUpdated(peer);
|
||||
overview->mediaOverviewUpdated(peer, type);
|
||||
|
||||
int32 mask = 0;
|
||||
History *h = peer ? App::historyLoaded(peer->id) : 0;
|
||||
@@ -1303,7 +1347,7 @@ void MainWidget::photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpR
|
||||
h->_overview[type].push_front(item->id);
|
||||
}
|
||||
}
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(h->peer);
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(h->peer, type);
|
||||
}
|
||||
|
||||
void MainWidget::partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
||||
@@ -1378,16 +1422,16 @@ void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
|
||||
if (audio->loader->done()) {
|
||||
audio->finish();
|
||||
QString already = audio->already();
|
||||
bool play = audio->openOnSave > 0 && audioPlayer();
|
||||
bool play = audio->openOnSave > 0 && audio->openOnSaveMsgId && audioPlayer();
|
||||
if ((!already.isEmpty() && audio->openOnSave) || (!audio->data.isEmpty() && play)) {
|
||||
if (play) {
|
||||
AudioData *playing = 0;
|
||||
AudioMsgId playing;
|
||||
AudioPlayerState state = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &state);
|
||||
if (playing == audio && state != AudioPlayerStopped) {
|
||||
audioPlayer()->pauseresume();
|
||||
if (playing.msgId == audio->openOnSaveMsgId && !(state & AudioPlayerStoppedMask) && state != AudioPlayerFinishing) {
|
||||
audioPlayer()->pauseresume(OverviewAudios);
|
||||
} else {
|
||||
audioPlayer()->play(audio);
|
||||
audioPlayer()->play(AudioMsgId(audio, audio->openOnSaveMsgId));
|
||||
if (App::main()) App::main()->audioMarkRead(audio);
|
||||
}
|
||||
} else {
|
||||
@@ -1411,15 +1455,17 @@ void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::audioPlayProgress(AudioData *audio) {
|
||||
AudioData *playing = 0;
|
||||
void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
|
||||
AudioMsgId playing;
|
||||
AudioPlayerState state = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &state);
|
||||
if (playing == audio && state == AudioPlayerStoppedAtStart) {
|
||||
audioPlayer()->clearStoppedAtStart(audio);
|
||||
if (playing == audioId && state == AudioPlayerStoppedAtStart) {
|
||||
audioPlayer()->clearStoppedAtStart(audioId);
|
||||
|
||||
AudioData *audio = audioId.audio;
|
||||
QString already = audio->already(true);
|
||||
if (already.isEmpty() && !audio->data.isEmpty()) {
|
||||
bool mp3 = (audio->mime == QLatin1String("audio/mp3"));
|
||||
bool mp3 = (audio->mime == qstr("audio/mp3"));
|
||||
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false);
|
||||
if (!filename.isEmpty()) {
|
||||
QFile f(filename);
|
||||
@@ -1438,12 +1484,78 @@ void MainWidget::audioPlayProgress(AudioData *audio) {
|
||||
}
|
||||
}
|
||||
|
||||
const AudioItems &items(App::audioItems());
|
||||
AudioItems::const_iterator i = items.constFind(audio);
|
||||
if (i != items.cend()) {
|
||||
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
|
||||
msgUpdated(j.key()->history()->peer->id, j.key());
|
||||
if (HistoryItem *item = App::histItemById(audioId.msgId)) {
|
||||
msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::documentPlayProgress(const SongMsgId &songId) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
int64 playingPosition = 0, playingDuration = 0;
|
||||
int32 playingFrequency = 0;
|
||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||
if (playing == songId && playingState == AudioPlayerStoppedAtStart) {
|
||||
playingState = AudioPlayerStopped;
|
||||
audioPlayer()->clearStoppedAtStart(songId);
|
||||
|
||||
DocumentData *document = songId.song;
|
||||
QString already = document->already(true);
|
||||
if (already.isEmpty() && !document->data.isEmpty()) {
|
||||
QString name = document->name, filter;
|
||||
MimeType mimeType = mimeTypeForName(document->mime);
|
||||
QStringList p = mimeType.globPatterns();
|
||||
QString pattern = p.isEmpty() ? QString() : p.front();
|
||||
if (name.isEmpty()) {
|
||||
name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
|
||||
}
|
||||
if (pattern.isEmpty()) {
|
||||
filter = qsl("All files (*.*)");
|
||||
} else {
|
||||
filter = mimeType.filterString() + qsl(";;All files (*.*)");
|
||||
}
|
||||
QString filename = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, false);
|
||||
if (!filename.isEmpty()) {
|
||||
QFile f(filename);
|
||||
if (f.open(QIODevice::WriteOnly)) {
|
||||
if (f.write(document->data) == document->data.size()) {
|
||||
f.close();
|
||||
already = filename;
|
||||
document->location = FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename);
|
||||
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputDocumentFileLocation), document->dc, document->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!already.isEmpty()) {
|
||||
psOpenFile(already);
|
||||
}
|
||||
}
|
||||
|
||||
if (playing == songId) {
|
||||
_player.updateState(playing, playingState, playingPosition, playingDuration, playingFrequency);
|
||||
|
||||
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||
if (_player.isHidden()) {
|
||||
_player.clearSelection();
|
||||
_player.show();
|
||||
_playerHeight = _contentScrollAddToY = _player.height();
|
||||
resizeEvent(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HistoryItem *item = App::histItemById(songId.msgId)) {
|
||||
msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::hidePlayer() {
|
||||
if (!_player.isHidden()) {
|
||||
_player.hide();
|
||||
_contentScrollAddToY = -_player.height();
|
||||
_playerHeight = 0;
|
||||
resizeEvent(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1463,16 +1575,32 @@ void MainWidget::audioLoadRetry() {
|
||||
}
|
||||
|
||||
void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
||||
bool songPlayActivated = false;
|
||||
DocumentData *document = App::document(loader->objId());
|
||||
if (document->loader) {
|
||||
if (document->loader->done()) {
|
||||
document->finish();
|
||||
QString already = document->already();
|
||||
if (!already.isEmpty() && document->openOnSave) {
|
||||
if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
|
||||
|
||||
HistoryItem *item = (document->openOnSave && document->openOnSaveMsgId) ? App::histItemById(document->openOnSaveMsgId) : 0;
|
||||
bool play = document->song() && audioPlayer() && document->openOnSave && item;
|
||||
if ((!already.isEmpty() || (!document->data.isEmpty() && play)) && document->openOnSave) {
|
||||
if (play) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &playingState);
|
||||
if (playing.msgId == item->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||
audioPlayer()->pauseresume(OverviewDocuments);
|
||||
} else {
|
||||
SongMsgId song(document, item->id);
|
||||
audioPlayer()->play(song);
|
||||
if (App::main()) App::main()->documentPlayProgress(song);
|
||||
}
|
||||
|
||||
songPlayActivated = true;
|
||||
} else if(document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
|
||||
QImageReader reader(already);
|
||||
if (reader.canRead()) {
|
||||
HistoryItem *item = App::histItemById(document->openOnSaveMsgId);
|
||||
if (reader.supportsAnimation() && reader.imageCount() > 1 && item) {
|
||||
startGif(item, already);
|
||||
} else if (item) {
|
||||
@@ -1502,6 +1630,21 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
||||
}
|
||||
}
|
||||
App::wnd()->documentUpdated(document);
|
||||
|
||||
if (!songPlayActivated && audioPlayer()) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
int64 playingPosition = 0, playingDuration = 0;
|
||||
int32 playingFrequency = 0;
|
||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||
if (playing.song == document && !_player.isHidden()) {
|
||||
if (document->loader) {
|
||||
_player.updateState(playing, playingState, playingPosition, playingDuration, playingFrequency);
|
||||
} else {
|
||||
audioPlayer()->play(playing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::documentLoadFailed(mtpFileLoader *loader, bool started) {
|
||||
@@ -1761,19 +1904,19 @@ void MainWidget::showPeer(quint64 peerId, qint32 msgId, bool back, bool force) {
|
||||
hider = 0;
|
||||
}
|
||||
if (force || !selectingPeer()) {
|
||||
if (!animating() && ((history.isHidden() && (profile || overview)) || (!cWideMode() && (history.isHidden() || !peerId)))) {
|
||||
if (!animating() && ((history.isHidden() && history.activePeer() && (profile || overview)) || (!cWideMode() && (history.isHidden() || !peerId)))) {
|
||||
dialogs.enableShadow(false);
|
||||
if (peerId) {
|
||||
_topBar.enableShadow(false);
|
||||
if (cWideMode()) {
|
||||
animCache = myGrab(this, QRect(_dialogsWidth, st::topBarHeight, width() - _dialogsWidth, height() - st::topBarHeight));
|
||||
animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight + st::topBarHeight, width() - _dialogsWidth, height() - _playerHeight - st::topBarHeight));
|
||||
} else {
|
||||
animCache = myGrab(this, QRect(0, st::topBarHeight, _dialogsWidth, height() - st::topBarHeight));
|
||||
animCache = myGrab(this, QRect(0, _playerHeight + st::topBarHeight, _dialogsWidth, height() - _playerHeight - st::topBarHeight));
|
||||
}
|
||||
} else if (cWideMode()) {
|
||||
animCache = myGrab(this, QRect(_dialogsWidth, 0, width() - _dialogsWidth, height()));
|
||||
animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight));
|
||||
} else {
|
||||
animCache = myGrab(this, QRect(0, 0, _dialogsWidth, height()));
|
||||
animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight));
|
||||
}
|
||||
if (peerId || cWideMode()) {
|
||||
animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight));
|
||||
@@ -1822,6 +1965,8 @@ void MainWidget::showPeer(quint64 peerId, qint32 msgId, bool back, bool force) {
|
||||
history.show();
|
||||
if (!animCache.isNull()) {
|
||||
history.animShow(animCache, animTopBarCache, back);
|
||||
} else {
|
||||
QTimer::singleShot(0, this, SLOT(setInnerFocus()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1871,8 +2016,12 @@ PeerData *MainWidget::profilePeer() {
|
||||
return profile ? profile->peer() : 0;
|
||||
}
|
||||
|
||||
PeerData *MainWidget::overviewPeer() {
|
||||
return overview ? overview->peer() : 0;
|
||||
}
|
||||
|
||||
bool MainWidget::mediaTypeSwitch() {
|
||||
if (!overview) return false;
|
||||
if (!overview || (overview->type() == OverviewAudioDocuments)) return false;
|
||||
|
||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
||||
if (!(_mediaTypeMask & ~(1 << i))) {
|
||||
@@ -1887,13 +2036,21 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||
if (overview && overview->peer() == peer) {
|
||||
if (overview->type() != type) {
|
||||
overview->switchType(type);
|
||||
} else if (type == OverviewAudioDocuments) { // hack for player
|
||||
showBackFromStack();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
dialogs.enableShadow(false);
|
||||
_topBar.enableShadow(false);
|
||||
QPixmap animCache = myGrab(this, history.geometry()), animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight));
|
||||
QRect topBarRect = QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight);
|
||||
QRect historyRect = QRect(history.x(), topBarRect.y() + topBarRect.height(), history.width(), history.y() + history.height() - topBarRect.y() - topBarRect.height());
|
||||
QPixmap animCache, animTopBarCache;
|
||||
if (!animating() && (!cWideMode() || profile || overview || history.peer())) {
|
||||
animCache = myGrab(this, historyRect);
|
||||
animTopBarCache = myGrab(this, topBarRect);
|
||||
}
|
||||
dialogs.enableShadow();
|
||||
_topBar.enableShadow();
|
||||
if (!back) {
|
||||
@@ -1901,7 +2058,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||
_stack.push_back(new StackItemOverview(overview->peer(), overview->type(), overview->lastWidth(), overview->lastScrollTop()));
|
||||
} else if (profile) {
|
||||
_stack.push_back(new StackItemProfile(profile->peer(), profile->lastScrollTop(), profile->allMediaShown()));
|
||||
} else {
|
||||
} else if (history.peer()) {
|
||||
_stack.push_back(new StackItemHistory(history.peer(), history.lastWidth(), history.lastScrollTop(), history.replyReturns(), history.kbWasHidden()));
|
||||
}
|
||||
}
|
||||
@@ -1920,14 +2077,20 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||
}
|
||||
overview = new OverviewWidget(this, peer, type);
|
||||
_mediaTypeMask = 0;
|
||||
mediaOverviewUpdated(peer);
|
||||
_topBar.show();
|
||||
resizeEvent(0);
|
||||
overview->animShow(animCache, animTopBarCache, back, lastScrollTop);
|
||||
mediaOverviewUpdated(peer, type);
|
||||
if (!animCache.isNull()) {
|
||||
overview->animShow(animCache, animTopBarCache, back, lastScrollTop);
|
||||
} else {
|
||||
overview->fastShow();
|
||||
}
|
||||
history.animStop();
|
||||
history.showPeer(0, 0, false, true);
|
||||
history.hide();
|
||||
if (!cWideMode()) dialogs.hide();
|
||||
_topBar.raise();
|
||||
_player.raise();
|
||||
dialogs.raise();
|
||||
_mediaType.raise();
|
||||
if (hider) hider->raise();
|
||||
@@ -1973,6 +2136,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop,
|
||||
history.showPeer(0, 0, false, true);
|
||||
history.hide();
|
||||
_topBar.raise();
|
||||
_player.raise();
|
||||
dialogs.raise();
|
||||
_mediaType.raise();
|
||||
if (hider) hider->raise();
|
||||
@@ -1980,7 +2144,16 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop,
|
||||
}
|
||||
|
||||
void MainWidget::showBackFromStack() {
|
||||
if (_stack.isEmpty() || selectingPeer()) return;
|
||||
if (selectingPeer()) return;
|
||||
if (_stack.isEmpty()) {
|
||||
if (cWideMode()) {
|
||||
showPeer(0, 0, false, true);
|
||||
QTimer::singleShot(0, this, SLOT(setInnerFocus()));
|
||||
} else {
|
||||
onShowDialogs();
|
||||
}
|
||||
return;
|
||||
}
|
||||
StackItem *item = _stack.back();
|
||||
_stack.pop_back();
|
||||
if (item->type() == HistoryStackItem) {
|
||||
@@ -2062,6 +2235,7 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
|
||||
|
||||
void MainWidget::sentUpdatesReceived(const MTPUpdates &result) {
|
||||
handleUpdates(result);
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
void MainWidget::msgUpdated(PeerId peer, const HistoryItem *msg) {
|
||||
@@ -2225,19 +2399,26 @@ void MainWidget::resizeEvent(QResizeEvent *e) {
|
||||
if (cWideMode()) {
|
||||
_dialogsWidth = snap<int>((width() * 5) / 14, st::dlgMinWidth, st::dlgMaxWidth);
|
||||
dialogs.setGeometry(0, 0, _dialogsWidth + st::dlgShadow, height());
|
||||
_topBar.setGeometry(_dialogsWidth, 0, width() - _dialogsWidth, st::topBarHeight + st::titleShadow);
|
||||
history.setGeometry(_dialogsWidth, tbh, width() - _dialogsWidth, height() - tbh);
|
||||
_player.setGeometry(_dialogsWidth, 0, width() - _dialogsWidth, _player.height());
|
||||
_topBar.setGeometry(_dialogsWidth, _playerHeight, width() - _dialogsWidth, st::topBarHeight + st::titleShadow);
|
||||
history.setGeometry(_dialogsWidth, _playerHeight + tbh, width() - _dialogsWidth, height() - _playerHeight - tbh);
|
||||
if (hider) hider->setGeometry(QRect(_dialogsWidth, 0, width() - _dialogsWidth, height()));
|
||||
} else {
|
||||
_dialogsWidth = width();
|
||||
dialogs.setGeometry(0, 0, _dialogsWidth + st::dlgShadow, height());
|
||||
_topBar.setGeometry(0, 0, _dialogsWidth, st::topBarHeight + st::titleShadow);
|
||||
history.setGeometry(0, tbh, _dialogsWidth, height() - tbh);
|
||||
_player.setGeometry(0, 0, _dialogsWidth, _player.height());
|
||||
dialogs.setGeometry(0, _playerHeight, _dialogsWidth + st::dlgShadow, height() - _playerHeight);
|
||||
_topBar.setGeometry(0, _playerHeight, _dialogsWidth, st::topBarHeight + st::titleShadow);
|
||||
history.setGeometry(0, _playerHeight + tbh, _dialogsWidth, height() - _playerHeight - tbh);
|
||||
if (hider) hider->setGeometry(QRect(0, 0, _dialogsWidth, height()));
|
||||
}
|
||||
_mediaType.move(width() - _mediaType.width(), st::topBarHeight);
|
||||
_mediaType.move(width() - _mediaType.width(), _playerHeight + st::topBarHeight);
|
||||
if (profile) profile->setGeometry(history.geometry());
|
||||
if (overview) overview->setGeometry(history.geometry());
|
||||
_contentScrollAddToY = 0;
|
||||
}
|
||||
|
||||
int32 MainWidget::contentScrollAddToY() const {
|
||||
return _contentScrollAddToY;
|
||||
}
|
||||
|
||||
void MainWidget::keyPressEvent(QKeyEvent *e) {
|
||||
@@ -2267,8 +2448,14 @@ void MainWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
|
||||
}
|
||||
|
||||
void MainWidget::topBarShadowParams(int32 &x, float64 &o) {
|
||||
if (!profile && !overview && dialogs.isHidden()) {
|
||||
history.topBarShadowParams(x, o);
|
||||
if (!cWideMode() && dialogs.isHidden()) {
|
||||
if (profile) {
|
||||
if (!history.activePeer()) profile->topBarShadowParams(x, o);
|
||||
} else if (overview) {
|
||||
if (!history.activePeer()) overview->topBarShadowParams(x, o);
|
||||
} else {
|
||||
history.topBarShadowParams(x, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2296,6 +2483,10 @@ TopBarWidget *MainWidget::topBar() {
|
||||
return &_topBar;
|
||||
}
|
||||
|
||||
PlayerWidget *MainWidget::player() {
|
||||
return &_player;
|
||||
}
|
||||
|
||||
void MainWidget::onTopBarClick() {
|
||||
if (profile) {
|
||||
profile->topBarClick();
|
||||
@@ -2389,6 +2580,8 @@ void MainWidget::gotState(const MTPupdates_State &state) {
|
||||
|
||||
dialogs.loadDialogs();
|
||||
updateOnline();
|
||||
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||
@@ -2404,6 +2597,8 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||
noUpdatesTimer.start(NoUpdatesTimeout);
|
||||
|
||||
updInited = true;
|
||||
|
||||
App::emitPeerUpdated();
|
||||
} break;
|
||||
case mtpc_updates_differenceSlice: {
|
||||
const MTPDupdates_differenceSlice &d(diff.c_updates_differenceSlice());
|
||||
@@ -2416,6 +2611,8 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||
|
||||
MTP_LOG(0, ("getDifference { good - after a slice of difference was received }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
||||
getDifference();
|
||||
|
||||
App::emitPeerUpdated();
|
||||
} break;
|
||||
case mtpc_updates_difference: {
|
||||
const MTPDupdates_difference &d(diff.c_updates_difference());
|
||||
@@ -2443,6 +2640,7 @@ void MainWidget::applySkippedPtsUpdates() {
|
||||
}
|
||||
--updSkipPtsUpdateLevel;
|
||||
clearSkippedPtsUpdates();
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
void MainWidget::clearSkippedPtsUpdates() {
|
||||
@@ -2472,8 +2670,8 @@ bool MainWidget::updPtsUpdated(int pts, int ptsCount) { // return false if need
|
||||
|
||||
void MainWidget::feedDifference(const MTPVector<MTPUser> &users, const MTPVector<MTPChat> &chats, const MTPVector<MTPMessage> &msgs, const MTPVector<MTPUpdate> &other) {
|
||||
App::wnd()->checkAutoLock();
|
||||
App::feedUsers(users);
|
||||
App::feedChats(chats);
|
||||
App::feedUsers(users, false);
|
||||
App::feedChats(chats, false);
|
||||
feedMessageIds(other);
|
||||
App::feedMsgs(msgs, 1);
|
||||
feedUpdates(other, true);
|
||||
@@ -2550,18 +2748,18 @@ bool MainWidget::started() {
|
||||
|
||||
void MainWidget::openLocalUrl(const QString &url) {
|
||||
QString u(url.trimmed());
|
||||
if (u.startsWith(QLatin1String("tg://resolve"), Qt::CaseInsensitive)) {
|
||||
if (u.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) {
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://resolve/?\\?domain=([a-zA-Z0-9\\.\\_]+)(&(start|startgroup)=([a-zA-Z0-9\\.\\_\\-]+))?(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
|
||||
if (m.hasMatch()) {
|
||||
QString start = m.captured(3), startToken = m.captured(4);
|
||||
openUserByName(m.captured(1), (start == qsl("startgroup")), startToken);
|
||||
}
|
||||
} else if (u.startsWith(QLatin1String("tg://join"), Qt::CaseInsensitive)) {
|
||||
} else if (u.startsWith(qstr("tg://join"), Qt::CaseInsensitive)) {
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
|
||||
if (m.hasMatch()) {
|
||||
joinGroupByHash(m.captured(1));
|
||||
}
|
||||
} else if (u.startsWith(QLatin1String("tg://addstickers"), Qt::CaseInsensitive)) {
|
||||
} else if (u.startsWith(qstr("tg://addstickers"), Qt::CaseInsensitive)) {
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
|
||||
if (m.hasMatch()) {
|
||||
stickersBox(MTP_inputStickerSetShortName(MTP_string(m.captured(1))));
|
||||
@@ -2845,7 +3043,7 @@ void MainWidget::updateNotifySetting(PeerData *peer, bool enabled) {
|
||||
}
|
||||
|
||||
void MainWidget::incrementSticker(DocumentData *sticker) {
|
||||
if (!sticker || !sticker->sticker) return;
|
||||
if (!sticker || !sticker->sticker()) return;
|
||||
|
||||
RecentStickerPack &recent(cGetRecentStickers());
|
||||
RecentStickerPack::iterator i = recent.begin(), e = recent.end();
|
||||
@@ -2886,13 +3084,13 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
|
||||
bool found = false;
|
||||
uint64 setId = 0;
|
||||
QString setName;
|
||||
switch (sticker->sticker->set.type()) {
|
||||
case mtpc_inputStickerSetID: setId = sticker->sticker->set.c_inputStickerSetID().vid.v; break;
|
||||
case mtpc_inputStickerSetShortName: setName = qs(sticker->sticker->set.c_inputStickerSetShortName().vshort_name).toLower().trimmed(); break;
|
||||
switch (sticker->sticker()->set.type()) {
|
||||
case mtpc_inputStickerSetID: setId = sticker->sticker()->set.c_inputStickerSetID().vid.v; break;
|
||||
case mtpc_inputStickerSetShortName: setName = qs(sticker->sticker()->set.c_inputStickerSetShortName().vshort_name).toLower().trimmed(); break;
|
||||
}
|
||||
StickerSets &sets(cRefStickerSets());
|
||||
for (StickerSets::const_iterator i = sets.cbegin(); i != sets.cend(); ++i) {
|
||||
if (i->id == CustomStickerSetId || (setId && i->id == setId) || (!setName.isEmpty() && i->shortName.toLower().trimmed() == setName) || (!setId && setName.isEmpty() && i->id == DefaultStickerSetId)) {
|
||||
if (i->id == CustomStickerSetId || i->id == DefaultStickerSetId || (setId && i->id == setId) || (!setName.isEmpty() && i->shortName.toLower().trimmed() == setName)) {
|
||||
for (int32 j = 0, l = i->stickers.size(); j < l; ++j) {
|
||||
if (i->stickers.at(j) == sticker) {
|
||||
found = true;
|
||||
@@ -2905,9 +3103,10 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
|
||||
if (!found) {
|
||||
StickerSets::iterator it = sets.find(CustomStickerSetId);
|
||||
if (it == sets.cend()) {
|
||||
it = sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString()));
|
||||
it = sets.insert(CustomStickerSetId, StickerSet(CustomStickerSetId, 0, lang(lng_custom_stickers), QString(), 0, 0, 0));
|
||||
}
|
||||
it->stickers.push_back(sticker);
|
||||
++it->count;
|
||||
Local::writeStickers();
|
||||
}
|
||||
history.updateRecentStickers();
|
||||
@@ -3050,7 +3249,8 @@ void MainWidget::updateReceived(const mtpPrime *from, const mtpPrime *end) {
|
||||
noUpdatesTimer.start(NoUpdatesTimeout);
|
||||
|
||||
handleUpdates(updates);
|
||||
} catch(mtpErrorUnexpected &e) { // just some other type
|
||||
App::emitPeerUpdated();
|
||||
} catch (mtpErrorUnexpected &e) { // just some other type
|
||||
}
|
||||
}
|
||||
update();
|
||||
@@ -3068,8 +3268,8 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
}
|
||||
}
|
||||
|
||||
App::feedChats(d.vchats);
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedUsers(d.vusers, false);
|
||||
App::feedChats(d.vchats, false);
|
||||
feedUpdates(d.vupdates);
|
||||
|
||||
updSetState(0, d.vdate.v, updQts, d.vseq.v);
|
||||
@@ -3085,8 +3285,8 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
}
|
||||
}
|
||||
|
||||
App::feedChats(d.vchats);
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedUsers(d.vusers, false);
|
||||
App::feedChats(d.vchats, false);
|
||||
feedUpdates(d.vupdates);
|
||||
|
||||
updSetState(0, d.vdate.v, updQts, d.vseq.v);
|
||||
@@ -3210,6 +3410,9 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
if (item->isMediaUnread()) {
|
||||
item->markMediaRead();
|
||||
msgUpdated(item->history()->peer->id, item);
|
||||
if (item->out() && !item->history()->peer->chat) {
|
||||
item->history()->peer->asUser()->madeAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3276,17 +3479,17 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateChatParticipants: {
|
||||
const MTPDupdateChatParticipants &d(update.c_updateChatParticipants());
|
||||
App::feedParticipants(d.vparticipants, true);
|
||||
App::feedParticipants(d.vparticipants, true, false);
|
||||
} break;
|
||||
|
||||
case mtpc_updateChatParticipantAdd: {
|
||||
const MTPDupdateChatParticipantAdd &d(update.c_updateChatParticipantAdd());
|
||||
App::feedParticipantAdd(d);
|
||||
App::feedParticipantAdd(d, false);
|
||||
} break;
|
||||
|
||||
case mtpc_updateChatParticipantDelete: {
|
||||
const MTPDupdateChatParticipantDelete &d(update.c_updateChatParticipantDelete());
|
||||
App::feedParticipantDelete(d);
|
||||
App::feedParticipantDelete(d, false);
|
||||
} break;
|
||||
|
||||
case mtpc_updateUserStatus: {
|
||||
@@ -3305,7 +3508,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
case mtpc_userStatusOffline: user->onlineTill = d.vstatus.c_userStatusOffline().vwas_online.v; break;
|
||||
case mtpc_userStatusOnline: user->onlineTill = d.vstatus.c_userStatusOnline().vexpires.v; break;
|
||||
}
|
||||
if (App::main()) App::main()->peerUpdated(user);
|
||||
App::markPeerUpdated(user);
|
||||
}
|
||||
if (d.vuser_id.v == MTP::authedId()) {
|
||||
if (d.vstatus.type() == mtpc_userStatusOffline || d.vstatus.type() == mtpc_userStatusEmpty) {
|
||||
@@ -3328,7 +3531,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
} else {
|
||||
user->setName(textOneLine(user->firstName), textOneLine(user->lastName), user->nameOrPhone, textOneLine(qs(d.vusername)));
|
||||
}
|
||||
if (App::main()) App::main()->peerUpdated(user);
|
||||
App::markPeerUpdated(user);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -3342,7 +3545,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
user->photosCount = -1;
|
||||
user->photos.clear();
|
||||
} else {
|
||||
if (user->photoId) {
|
||||
if (user->photoId && user->photoId != UnknownPeerPhotoId) {
|
||||
if (user->photosCount > 0) ++user->photosCount;
|
||||
user->photos.push_front(App::photo(user->photoId));
|
||||
} else {
|
||||
@@ -3350,8 +3553,8 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
user->photos.clear();
|
||||
}
|
||||
}
|
||||
if (App::main()) App::main()->peerUpdated(user);
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(user);
|
||||
App::markPeerUpdated(user);
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(user, OverviewCount);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -3367,7 +3570,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateContactLink: {
|
||||
const MTPDupdateContactLink &d(update.c_updateContactLink());
|
||||
App::feedUserLink(d.vuser_id, d.vmy_link, d.vforeign_link);
|
||||
App::feedUserLink(d.vuser_id, d.vmy_link, d.vforeign_link, false);
|
||||
} break;
|
||||
|
||||
case mtpc_updateNotifySettings: {
|
||||
@@ -3386,7 +3589,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
if (user) {
|
||||
user->setPhone(qs(d.vphone));
|
||||
user->setName(user->firstName, user->lastName, (user->contact || isServiceUser(user->id) || user->phone.isEmpty()) ? QString() : App::formatPhone(user->phone), user->username);
|
||||
if (App::main()) App::main()->peerUpdated(user);
|
||||
App::markPeerUpdated(user);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include "historywidget.h"
|
||||
#include "profilewidget.h"
|
||||
#include "overviewwidget.h"
|
||||
#include "playerwidget.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
class Window;
|
||||
@@ -163,6 +164,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum ForwardWhatMessages {
|
||||
ForwardSelectedMessages,
|
||||
ForwardContextMessage,
|
||||
ForwardPressedMessage,
|
||||
ForwardPressedLinkMessage
|
||||
};
|
||||
|
||||
class MainWidget : public QWidget, public Animated, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -182,6 +190,9 @@ public:
|
||||
void topBarShadowParams(int32 &x, float64 &o);
|
||||
TopBarWidget *topBar();
|
||||
|
||||
PlayerWidget *player();
|
||||
int32 contentScrollAddToY() const;
|
||||
|
||||
void animShow(const QPixmap &bgAnimCache, bool back = false);
|
||||
bool animStep(float64 ms);
|
||||
|
||||
@@ -226,6 +237,7 @@ public:
|
||||
PeerData *activePeer();
|
||||
MsgId activeMsgId();
|
||||
PeerData *profilePeer();
|
||||
PeerData *overviewPeer();
|
||||
bool mediaTypeSwitch();
|
||||
void showPeerProfile(PeerData *peer, bool back = false, int32 lastScrollTop = -1, bool allMediaShown = false);
|
||||
void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1);
|
||||
@@ -254,14 +266,17 @@ public:
|
||||
void shareContactLayer(UserData *contact);
|
||||
void hiderLayer(HistoryHider *h);
|
||||
void noHider(HistoryHider *destroyed);
|
||||
void onForward(const PeerId &peer, bool forwardSelected);
|
||||
void onForward(const PeerId &peer, ForwardWhatMessages what);
|
||||
void onShareContact(const PeerId &peer, UserData *contact);
|
||||
void onSendPaths(const PeerId &peer);
|
||||
void onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data);
|
||||
bool selectingPeer(bool withConfirm = false);
|
||||
void offerPeer(PeerId peer);
|
||||
void focusPeerSelect();
|
||||
void dialogsActivate();
|
||||
|
||||
DragState getDragState(const QMimeData *mime);
|
||||
|
||||
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
||||
void deleteHistory(PeerData *peer, const MTPUpdates &updates);
|
||||
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
||||
@@ -303,7 +318,7 @@ public:
|
||||
|
||||
void searchMessages(const QString &query);
|
||||
void preloadOverviews(PeerData *peer);
|
||||
void mediaOverviewUpdated(PeerData *peer);
|
||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||
void itemRemoved(HistoryItem *item);
|
||||
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
|
||||
@@ -352,6 +367,7 @@ public:
|
||||
void updateMutedIn(int32 seconds);
|
||||
|
||||
void updateStickers();
|
||||
void botCommandsChanged(UserData *bot);
|
||||
|
||||
~MainWidget();
|
||||
|
||||
@@ -376,10 +392,12 @@ public slots:
|
||||
void audioLoadProgress(mtpFileLoader *loader);
|
||||
void audioLoadFailed(mtpFileLoader *loader, bool started);
|
||||
void audioLoadRetry();
|
||||
void audioPlayProgress(AudioData *audio);
|
||||
void audioPlayProgress(const AudioMsgId &audioId);
|
||||
void documentLoadProgress(mtpFileLoader *loader);
|
||||
void documentLoadFailed(mtpFileLoader *loader, bool started);
|
||||
void documentLoadRetry();
|
||||
void documentPlayProgress(const SongMsgId &songId);
|
||||
void hidePlayer();
|
||||
|
||||
void setInnerFocus();
|
||||
void dialogsCancelled();
|
||||
@@ -479,12 +497,16 @@ private:
|
||||
HistoryWidget history;
|
||||
ProfileWidget *profile;
|
||||
OverviewWidget *overview;
|
||||
PlayerWidget _player;
|
||||
TopBarWidget _topBar;
|
||||
ConfirmBox *_forwardConfirm; // for narrow mode
|
||||
HistoryHider *hider;
|
||||
StackItems _stack;
|
||||
QPixmap profileAnimCache;
|
||||
|
||||
int32 _playerHeight;
|
||||
int32 _contentScrollAddToY;
|
||||
|
||||
Dropdown _mediaType;
|
||||
int32 _mediaTypeMask;
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace {
|
||||
class SaveMsgLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(SaveMsgLink)
|
||||
|
||||
public:
|
||||
|
||||
SaveMsgLink(MediaView *view) : _view(view) {
|
||||
@@ -134,19 +136,19 @@ void MediaView::moveToScreen() {
|
||||
}
|
||||
|
||||
int32 navSkip = 2 * st::mvControlMargin + st::mvControlSize;
|
||||
_closeNav = rtlrect(width() - st::mvControlMargin - st::mvControlSize, st::mvControlMargin, st::mvControlSize, st::mvControlSize, width());
|
||||
_closeNav = myrtlrect(width() - st::mvControlMargin - st::mvControlSize, st::mvControlMargin, st::mvControlSize, st::mvControlSize);
|
||||
_closeNavIcon = centersprite(_closeNav, st::mvClose);
|
||||
_leftNav = rtlrect(st::mvControlMargin, navSkip, st::mvControlSize, height() - 2 * navSkip, width());
|
||||
_leftNav = myrtlrect(st::mvControlMargin, navSkip, st::mvControlSize, height() - 2 * navSkip);
|
||||
_leftNavIcon = centersprite(_leftNav, st::mvLeft);
|
||||
_rightNav = rtlrect(width() - st::mvControlMargin - st::mvControlSize, navSkip, st::mvControlSize, height() - 2 * navSkip, width());
|
||||
_rightNav = myrtlrect(width() - st::mvControlMargin - st::mvControlSize, navSkip, st::mvControlSize, height() - 2 * navSkip);
|
||||
_rightNavIcon = centersprite(_rightNav, st::mvRight);
|
||||
|
||||
_saveMsg.moveTo((width() - _saveMsg.width()) / 2, (height() - _saveMsg.height()) / 2);
|
||||
}
|
||||
|
||||
void MediaView::mediaOverviewUpdated(PeerData *peer) {
|
||||
void MediaView::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
if (!_photo && !_doc) return;
|
||||
if (_history && _history->peer == peer) {
|
||||
if (_history && _history->peer == peer && type == _overview) {
|
||||
_index = -1;
|
||||
for (int i = 0, l = _history->_overview[_overview].size(); i < l; ++i) {
|
||||
if (_history->_overview[_overview].at(i) == _msgid) {
|
||||
@@ -156,7 +158,7 @@ void MediaView::mediaOverviewUpdated(PeerData *peer) {
|
||||
}
|
||||
updateControls();
|
||||
preloadData(0);
|
||||
} else if (_user == peer) {
|
||||
} else if (_user == peer && type == OverviewCount) {
|
||||
if (!_photo) return;
|
||||
|
||||
_index = -1;
|
||||
@@ -190,7 +192,7 @@ void MediaView::changingMsgId(HistoryItem *row, MsgId newId) {
|
||||
if (row->id == _msgid) {
|
||||
_msgid = newId;
|
||||
}
|
||||
mediaOverviewUpdated(row->history()->peer);
|
||||
mediaOverviewUpdated(row->history()->peer, _overview);
|
||||
}
|
||||
|
||||
void MediaView::updateDocSize() {
|
||||
@@ -256,9 +258,9 @@ void MediaView::updateControls() {
|
||||
}
|
||||
|
||||
_saveVisible = ((_photo && _photo->full->loaded()) || (_doc && (!_doc->already(true).isEmpty() || (_current.isNull() && _currentGif.isNull()))));
|
||||
_saveNav = rtlrect(width() - st::mvIconSize.width() * 2, height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height(), width());
|
||||
_saveNav = myrtlrect(width() - st::mvIconSize.width() * 2, height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height());
|
||||
_saveNavIcon = centersprite(_saveNav, st::mvSave);
|
||||
_moreNav = rtlrect(width() - st::mvIconSize.width(), height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height(), width());
|
||||
_moreNav = myrtlrect(width() - st::mvIconSize.width(), height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height());
|
||||
_moreNavIcon = centersprite(_moreNav, st::mvMore);
|
||||
|
||||
QDateTime d(date(_photo ? _photo->date : _doc->date)), dNow(date(unixtime()));
|
||||
@@ -271,11 +273,11 @@ void MediaView::updateControls() {
|
||||
}
|
||||
if (_from) {
|
||||
_fromName.setText(st::mvFont, _from->name);
|
||||
_nameNav = rtlrect(st::mvTextLeft, height() - st::mvTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mvFont->height, width());
|
||||
_dateNav = rtlrect(st::mvTextLeft + _nameNav.width() + st::mvTextSkip, height() - st::mvTextTop, st::mvFont->m.width(_dateText), st::mvFont->height, width());
|
||||
_nameNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mvFont->height);
|
||||
_dateNav = myrtlrect(st::mvTextLeft + _nameNav.width() + st::mvTextSkip, height() - st::mvTextTop, st::mvFont->m.width(_dateText), st::mvFont->height);
|
||||
} else {
|
||||
_nameNav = QRect();
|
||||
_dateNav = rtlrect(st::mvTextLeft, height() - st::mvTextTop, st::mvFont->m.width(_dateText), st::mvFont->height, width());
|
||||
_dateNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, st::mvFont->m.width(_dateText), st::mvFont->height);
|
||||
}
|
||||
updateHeader();
|
||||
if (_photo) {
|
||||
@@ -347,7 +349,6 @@ bool MediaView::animStep(float64 msp) {
|
||||
a_cOpacity.finish();
|
||||
_controlsState = (_controlsState == ControlsShowing ? ControlsShown : ControlsHidden);
|
||||
setCursor(_controlsState == ControlsHidden ? Qt::BlankCursor : (_over == OverNone ? style::cur_default : style::cur_pointer));
|
||||
LOG(("Finished with controls!"));
|
||||
} else {
|
||||
a_cOpacity.update(dt, anim::linear);
|
||||
}
|
||||
@@ -408,7 +409,6 @@ void MediaView::close() {
|
||||
void MediaView::activateControls() {
|
||||
_controlsHideTimer.start(int(st::mvWaitHide));
|
||||
if (_controlsState == ControlsHiding || _controlsState == ControlsHidden) {
|
||||
LOG(("Showing controls.."));
|
||||
_controlsState = ControlsShowing;
|
||||
_controlsAnimStarted = getms();
|
||||
a_cOpacity.start(1);
|
||||
@@ -419,7 +419,6 @@ void MediaView::activateControls() {
|
||||
void MediaView::onHideControls(bool force) {
|
||||
if (!force && !_dropdown.isHidden()) return;
|
||||
if (_controlsState == ControlsHiding || _controlsState == ControlsHidden) return;
|
||||
LOG(("Hiding controls.."));
|
||||
_controlsState = ControlsHiding;
|
||||
_controlsAnimStarted = getms();
|
||||
a_cOpacity.start(0);
|
||||
@@ -680,7 +679,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) {
|
||||
_photo = photo;
|
||||
_overview = OverviewCount;
|
||||
if (_user) {
|
||||
if (_user->photos.isEmpty() && _user->photosCount < 0 && _user->photoId) {
|
||||
if (_user->photos.isEmpty() && _user->photosCount < 0 && _user->photoId && _user->photoId != UnknownPeerPhotoId) {
|
||||
_index = 0;
|
||||
}
|
||||
for (int i = 0, l = _user->photos.size(); i < l; ++i) {
|
||||
@@ -798,9 +797,9 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) {
|
||||
|
||||
_caption = Text();
|
||||
QString already = _doc->already(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();
|
||||
_current = _doc->sticker->img->pix();
|
||||
_current = _doc->sticker()->img->pix();
|
||||
} else if (!already.isEmpty()) {
|
||||
QImageReader reader(already);
|
||||
if (reader.canRead()) {
|
||||
@@ -826,33 +825,33 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) {
|
||||
style::sprite thumbs[] = { st::mvDocBlue, st::mvDocGreen, st::mvDocRed, st::mvDocYellow };
|
||||
style::color colors[] = { st::mvDocBlueColor, st::mvDocGreenColor, st::mvDocRedColor, st::mvDocYellowColor };
|
||||
QString name = _doc->name.toLower(), mime = _doc->mime.toLower();
|
||||
if (name.endsWith(QLatin1String(".doc")) ||
|
||||
name.endsWith(QLatin1String(".txt")) ||
|
||||
name.endsWith(QLatin1String(".psd")) ||
|
||||
mime.startsWith(QLatin1String("text/"))
|
||||
if (name.endsWith(qstr(".doc")) ||
|
||||
name.endsWith(qstr(".txt")) ||
|
||||
name.endsWith(qstr(".psd")) ||
|
||||
mime.startsWith(qstr("text/"))
|
||||
) {
|
||||
_docIcon = thumbs[0];
|
||||
_docIconColor = colors[0];
|
||||
} else if (
|
||||
name.endsWith(QLatin1String(".xls")) ||
|
||||
name.endsWith(QLatin1String(".csv"))
|
||||
name.endsWith(qstr(".xls")) ||
|
||||
name.endsWith(qstr(".csv"))
|
||||
) {
|
||||
_docIcon = thumbs[1];
|
||||
_docIconColor = colors[1];
|
||||
} else if (
|
||||
name.endsWith(QLatin1String(".pdf")) ||
|
||||
name.endsWith(QLatin1String(".ppt")) ||
|
||||
name.endsWith(QLatin1String(".key"))
|
||||
name.endsWith(qstr(".pdf")) ||
|
||||
name.endsWith(qstr(".ppt")) ||
|
||||
name.endsWith(qstr(".key"))
|
||||
) {
|
||||
_docIcon = thumbs[2];
|
||||
_docIconColor = colors[2];
|
||||
} else if (
|
||||
name.endsWith(QLatin1String(".zip")) ||
|
||||
name.endsWith(QLatin1String(".rar")) ||
|
||||
name.endsWith(QLatin1String(".ai")) ||
|
||||
name.endsWith(QLatin1String(".mp3")) ||
|
||||
name.endsWith(QLatin1String(".mov")) ||
|
||||
name.endsWith(QLatin1String(".avi"))
|
||||
name.endsWith(qstr(".zip")) ||
|
||||
name.endsWith(qstr(".rar")) ||
|
||||
name.endsWith(qstr(".ai")) ||
|
||||
name.endsWith(qstr(".mp3")) ||
|
||||
name.endsWith(qstr(".mov")) ||
|
||||
name.endsWith(qstr(".avi"))
|
||||
) {
|
||||
_docIcon = thumbs[3];
|
||||
_docIconColor = colors[3];
|
||||
@@ -904,7 +903,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) {
|
||||
// _docSize is updated in updateControls()
|
||||
|
||||
_docRect = QRect((width() - st::mvDocSize.width()) / 2, (height() - st::mvDocSize.height()) / 2, st::mvDocSize.width(), st::mvDocSize.height());
|
||||
_docIconRect = rtlrect(_docRect.x() + st::mvDocPadding, _docRect.y() + st::mvDocPadding, st::mvDocBlue.pxWidth(), st::mvDocBlue.pxHeight(), width());
|
||||
_docIconRect = myrtlrect(_docRect.x() + st::mvDocPadding, _docRect.y() + st::mvDocPadding, st::mvDocBlue.pxWidth(), st::mvDocBlue.pxHeight());
|
||||
} else if (!_current.isNull()) {
|
||||
_current.setDevicePixelRatio(cRetinaFactor());
|
||||
_w = _current.width() / cIntRetinaFactor();
|
||||
@@ -1008,7 +1007,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
|
||||
QRect imgRect(_x, _y, _w, _h);
|
||||
const QPixmap *toDraw = _currentGif.isNull() ? &_current : &_currentGif.current(_currentGif.w, _currentGif.h, false);
|
||||
if (imgRect.intersects(r)) {
|
||||
if (toDraw->hasAlpha() && (!_doc || !_doc->sticker || _doc->sticker->img->isNull())) {
|
||||
if (toDraw->hasAlpha() && (!_doc || !_doc->sticker() || _doc->sticker()->img->isNull())) {
|
||||
p.fillRect(imgRect, _transparentBrush);
|
||||
}
|
||||
if (_zoom) {
|
||||
@@ -1262,11 +1261,6 @@ void MediaView::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static uint64 t = getms();
|
||||
// uint64 t2 = getms();
|
||||
// LOG(("paint: %1, wait: %2, name: %3, icon: %4").arg(t2 - ms).arg(t2 - t).arg(logBool(name)).arg(logBool(icon)));
|
||||
// t = t2;
|
||||
}
|
||||
|
||||
void MediaView::keyPressEvent(QKeyEvent *e) {
|
||||
@@ -1413,7 +1407,7 @@ void MediaView::preloadData(int32 delta) {
|
||||
switch (media->type()) {
|
||||
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->full->load(); break;
|
||||
case MediaTypeDocument: static_cast<HistoryDocument*>(media)->document()->thumb->load(); break;
|
||||
case MediaTypeSticker: static_cast<HistorySticker*>(media)->document()->sticker->img->load(); break;
|
||||
case MediaTypeSticker: static_cast<HistorySticker*>(media)->document()->sticker()->img->load(); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1826,7 +1820,7 @@ void MediaView::findCurrent() {
|
||||
}
|
||||
}
|
||||
|
||||
if (_history->_overviewCount[_overview] < 0) {
|
||||
if (_history->_overviewCount[_overview] < 0 || (!_index && _history->_overviewCount[_overview] > 0)) {
|
||||
loadBack();
|
||||
}
|
||||
}
|
||||
@@ -1875,7 +1869,7 @@ void MediaView::userPhotosLoaded(UserData *u, const MTPphotos_Photos &photos, mt
|
||||
photo->thumb->load();
|
||||
u->photos.push_back(photo);
|
||||
}
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(u);
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(u, OverviewCount);
|
||||
}
|
||||
|
||||
void MediaView::updateHeader() {
|
||||
@@ -1911,7 +1905,7 @@ void MediaView::updateHeader() {
|
||||
hwidth = width() / 3;
|
||||
_headerText = st::mvThickFont->m.elidedText(_headerText, Qt::ElideMiddle, hwidth);
|
||||
}
|
||||
_headerNav = rtlrect(st::mvTextLeft, height() - st::mvHeaderTop, hwidth, st::mvThickFont->height, width());
|
||||
_headerNav = myrtlrect(st::mvTextLeft, height() - st::mvHeaderTop, hwidth, st::mvThickFont->height);
|
||||
}
|
||||
//
|
||||
//void MediaView::updatePolaroid() {
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
updateOver(mapFromGlobal(QCursor::pos()));
|
||||
}
|
||||
|
||||
void mediaOverviewUpdated(PeerData *peer);
|
||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||
void documentUpdated(DocumentData *doc);
|
||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||
void updateDocSize();
|
||||
|
||||
@@ -606,7 +606,7 @@ void MTPabstractTcpConnection::socketRead() {
|
||||
}
|
||||
|
||||
MTPautoConnection::MTPautoConnection(QThread *thread) : status(WaitingBoth),
|
||||
tcpNonce(MTP::nonce<MTPint128>()), httpNonce(MTP::nonce<MTPint128>()), _tcpTimeout(MTPMinReceiveDelay) {
|
||||
tcpNonce(MTP::nonce<MTPint128>()), httpNonce(MTP::nonce<MTPint128>()), _tcpTimeout(MTPMinReceiveDelay), _flags(0) {
|
||||
moveToThread(thread);
|
||||
|
||||
manager.moveToThread(thread);
|
||||
@@ -615,6 +615,7 @@ tcpNonce(MTP::nonce<MTPint128>()), httpNonce(MTP::nonce<MTPint128>()), _tcpTimeo
|
||||
httpStartTimer.moveToThread(thread);
|
||||
httpStartTimer.setSingleShot(true);
|
||||
connect(&httpStartTimer, SIGNAL(timeout()), this, SLOT(onHttpStart()));
|
||||
|
||||
tcpTimeoutTimer.moveToThread(thread);
|
||||
tcpTimeoutTimer.setSingleShot(true);
|
||||
connect(&tcpTimeoutTimer, SIGNAL(timeout()), this, SLOT(onTcpTimeoutTimer()));
|
||||
@@ -628,7 +629,7 @@ tcpNonce(MTP::nonce<MTPint128>()), httpNonce(MTP::nonce<MTPint128>()), _tcpTimeo
|
||||
|
||||
void MTPautoConnection::onHttpStart() {
|
||||
if (status == HttpReady) {
|
||||
DEBUG_LOG(("Connection Info: Http-transport chosen by timer"));
|
||||
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by timer").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingHttp;
|
||||
sock.disconnectFromHost();
|
||||
emit connected();
|
||||
@@ -639,7 +640,7 @@ void MTPautoConnection::onSocketConnected() {
|
||||
if (status == HttpReady || status == WaitingBoth || status == WaitingTcp) {
|
||||
mtpBuffer buffer(_preparePQFake(tcpNonce));
|
||||
|
||||
DEBUG_LOG(("Connection Info: sending fake req_pq through tcp transport"));
|
||||
DEBUG_LOG(("Connection Info: sending fake req_pq through TCP/%1 transport").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
|
||||
if (_tcpTimeout < 0) _tcpTimeout = -_tcpTimeout;
|
||||
tcpTimeoutTimer.start(_tcpTimeout);
|
||||
@@ -677,7 +678,7 @@ void MTPautoConnection::onSocketDisconnected() {
|
||||
} else if (status == WaitingTcp || status == UsingTcp) {
|
||||
emit disconnected();
|
||||
} else if (status == HttpReady) {
|
||||
DEBUG_LOG(("Connection Info: Http-transport chosen by socket disconnect"));
|
||||
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by socket disconnect").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingHttp;
|
||||
emit connected();
|
||||
}
|
||||
@@ -724,6 +725,7 @@ void MTPautoConnection::httpSend(mtpBuffer &buffer) {
|
||||
|
||||
void MTPautoConnection::disconnectFromServer() {
|
||||
if (status == FinishedWork) return;
|
||||
status = FinishedWork;
|
||||
|
||||
Requests copy = requests;
|
||||
requests.clear();
|
||||
@@ -740,7 +742,6 @@ void MTPautoConnection::disconnectFromServer() {
|
||||
sock.close();
|
||||
|
||||
httpStartTimer.stop();
|
||||
status = FinishedWork;
|
||||
}
|
||||
|
||||
void MTPautoConnection::connectToServer(const QString &addr, int32 port, int32 flags) {
|
||||
@@ -750,19 +751,20 @@ void MTPautoConnection::connectToServer(const QString &addr, int32 port, int32 f
|
||||
|
||||
_addr = addr;
|
||||
_port = port;
|
||||
_flags = flags;
|
||||
|
||||
connect(&sock, SIGNAL(readyRead()), this, SLOT(socketRead()));
|
||||
sock.connectToHost(QHostAddress(_addr), _port);
|
||||
|
||||
mtpBuffer buffer(_preparePQFake(httpNonce));
|
||||
|
||||
DEBUG_LOG(("Connection Info: sending fake req_pq through http transport"));
|
||||
DEBUG_LOG(("Connection Info: sending fake req_pq through HTTP/%1 transport").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
|
||||
httpSend(buffer);
|
||||
}
|
||||
|
||||
bool MTPautoConnection::isConnected() {
|
||||
return status != FinishedWork && !address.isEmpty();
|
||||
bool MTPautoConnection::isConnected() const {
|
||||
return (status == UsingTcp) || (status == UsingHttp);
|
||||
}
|
||||
|
||||
void MTPautoConnection::requestFinished(QNetworkReply *reply) {
|
||||
@@ -792,13 +794,14 @@ void MTPautoConnection::requestFinished(QNetworkReply *reply) {
|
||||
status = HttpReady;
|
||||
httpStartTimer.start(MTPTcpConnectionWaitTimeout);
|
||||
} else {
|
||||
DEBUG_LOG(("Connection Info: Http-transport chosen by pq-response, awaited"));
|
||||
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by pq-response, awaited").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingHttp;
|
||||
sock.disconnectFromHost();
|
||||
emit connected();
|
||||
}
|
||||
}
|
||||
} catch (Exception &e) {
|
||||
DEBUG_LOG(("Connection Error: exception in parsing HTTP fake pq-responce, %1").arg(e.what()));
|
||||
if (status == WaitingBoth) {
|
||||
status = WaitingTcp;
|
||||
} else {
|
||||
@@ -834,7 +837,7 @@ void MTPautoConnection::socketPacket(mtpPrime *packet, uint32 size) {
|
||||
status = WaitingHttp;
|
||||
sock.disconnectFromHost();
|
||||
} else if (status == HttpReady) {
|
||||
DEBUG_LOG(("Connection Info: Http-transport chosen by bad tcp response, ready"));
|
||||
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by bad tcp response, ready").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingHttp;
|
||||
sock.disconnectFromHost();
|
||||
emit connected();
|
||||
@@ -853,16 +856,17 @@ void MTPautoConnection::socketPacket(mtpPrime *packet, uint32 size) {
|
||||
MTPResPQ res_pq = _readPQFakeReply(data);
|
||||
const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
|
||||
if (res_pq_data.vnonce == tcpNonce) {
|
||||
DEBUG_LOG(("Connection Info: Tcp-transport chosen by pq-response"));
|
||||
DEBUG_LOG(("Connection Info: TCP/%1-transport chosen by pq-response").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingTcp;
|
||||
emit connected();
|
||||
}
|
||||
} catch (Exception &e) {
|
||||
DEBUG_LOG(("Connection Error: exception in parsing TCP fake pq-responce, %1").arg(e.what()));
|
||||
if (status == WaitingBoth) {
|
||||
status = WaitingHttp;
|
||||
sock.disconnectFromHost();
|
||||
} else if (status == HttpReady) {
|
||||
DEBUG_LOG(("Connection Info: Http-transport chosen by bad tcp response, awaited"));
|
||||
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by bad tcp response, awaited").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingHttp;
|
||||
sock.disconnectFromHost();
|
||||
emit connected();
|
||||
@@ -902,7 +906,7 @@ void MTPautoConnection::socketError(QAbstractSocket::SocketError e) {
|
||||
if (status == WaitingBoth) {
|
||||
status = WaitingHttp;
|
||||
} else if (status == HttpReady) {
|
||||
DEBUG_LOG(("Connection Info: Http-transport chosen by tcp error, ready"));
|
||||
DEBUG_LOG(("Connection Info: HTTP/%1-transport chosen by tcp error, ready").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingHttp;
|
||||
emit connected();
|
||||
} else if (status == WaitingTcp || status == UsingTcp) {
|
||||
@@ -912,16 +916,64 @@ void MTPautoConnection::socketError(QAbstractSocket::SocketError e) {
|
||||
}
|
||||
}
|
||||
|
||||
MTPtcpConnection::MTPtcpConnection(QThread *thread) {
|
||||
MTPtcpConnection::MTPtcpConnection(QThread *thread) : status(WaitingTcp),
|
||||
tcpNonce(MTP::nonce<MTPint128>()), _tcpTimeout(MTPMinReceiveDelay), _flags(0) {
|
||||
moveToThread(thread);
|
||||
|
||||
tcpTimeoutTimer.moveToThread(thread);
|
||||
tcpTimeoutTimer.setSingleShot(true);
|
||||
connect(&tcpTimeoutTimer, SIGNAL(timeout()), this, SLOT(onTcpTimeoutTimer()));
|
||||
|
||||
sock.moveToThread(thread);
|
||||
App::setProxySettings(sock);
|
||||
connect(&sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
|
||||
connect(&sock, SIGNAL(connected()), this, SIGNAL(connected()));
|
||||
connect(&sock, SIGNAL(disconnected()), this, SIGNAL(disconnected()));
|
||||
connect(&sock, SIGNAL(connected()), this, SLOT(onSocketConnected()));
|
||||
connect(&sock, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||
}
|
||||
|
||||
void MTPtcpConnection::onSocketConnected() {
|
||||
if (status == WaitingTcp) {
|
||||
mtpBuffer buffer(_preparePQFake(tcpNonce));
|
||||
|
||||
DEBUG_LOG(("Connection Info: sending fake req_pq through TCP/%1 transport").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
|
||||
if (_tcpTimeout < 0) _tcpTimeout = -_tcpTimeout;
|
||||
tcpTimeoutTimer.start(_tcpTimeout);
|
||||
|
||||
sendData(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void MTPtcpConnection::onTcpTimeoutTimer() {
|
||||
if (status == WaitingTcp) {
|
||||
if (_tcpTimeout < MTPMaxReceiveDelay) _tcpTimeout *= 2;
|
||||
_tcpTimeout = -_tcpTimeout;
|
||||
|
||||
QAbstractSocket::SocketState state = sock.state();
|
||||
if (state == QAbstractSocket::ConnectedState || state == QAbstractSocket::ConnectingState || state == QAbstractSocket::HostLookupState) {
|
||||
sock.disconnectFromHost();
|
||||
} else if (state != QAbstractSocket::ClosingState) {
|
||||
sock.connectToHost(QHostAddress(_addr), _port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MTPtcpConnection::onSocketDisconnected() {
|
||||
if (_tcpTimeout < 0) {
|
||||
_tcpTimeout = -_tcpTimeout;
|
||||
if (status == WaitingTcp) {
|
||||
sock.connectToHost(QHostAddress(_addr), _port);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (status == WaitingTcp || status == UsingTcp) {
|
||||
emit disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
void MTPtcpConnection::sendData(mtpBuffer &buffer) {
|
||||
if (status == FinishedWork) return;
|
||||
|
||||
if (buffer.size() < 3) {
|
||||
LOG(("TCP Error: writing bad packet, len = %1").arg(buffer.size() * sizeof(mtpPrime)));
|
||||
TCP_LOG(("TCP Error: bad packet %1").arg(mb(&buffer[0], buffer.size() * sizeof(mtpPrime)).str()));
|
||||
@@ -940,28 +992,51 @@ void MTPtcpConnection::sendData(mtpBuffer &buffer) {
|
||||
}
|
||||
|
||||
void MTPtcpConnection::disconnectFromServer() {
|
||||
if (status == FinishedWork) return;
|
||||
status = FinishedWork;
|
||||
|
||||
disconnect(&sock, SIGNAL(readyRead()), 0, 0);
|
||||
sock.close();
|
||||
}
|
||||
|
||||
void MTPtcpConnection::connectToServer(const QString &addr, int32 port, int32 flags) {
|
||||
_addr = addr;
|
||||
_port = port;
|
||||
_flags = flags;
|
||||
|
||||
connect(&sock, SIGNAL(readyRead()), this, SLOT(socketRead()));
|
||||
sock.connectToHost(QHostAddress(addr), port);
|
||||
sock.connectToHost(QHostAddress(_addr), _port);
|
||||
}
|
||||
|
||||
void MTPtcpConnection::socketPacket(mtpPrime *packet, uint32 size) {
|
||||
if (status == FinishedWork) return;
|
||||
|
||||
mtpBuffer data = _handleTcpResponse(packet, size);
|
||||
if (data.size() == 1) {
|
||||
bool mayBeBadKey = (data[0] == -404) && _sentEncrypted;
|
||||
emit error(mayBeBadKey);
|
||||
} else if (status == UsingTcp) {
|
||||
receivedQueue.push_back(data);
|
||||
emit receivedData();
|
||||
} else if (status == WaitingTcp) {
|
||||
tcpTimeoutTimer.stop();
|
||||
try {
|
||||
MTPResPQ res_pq = _readPQFakeReply(data);
|
||||
const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
|
||||
if (res_pq_data.vnonce == tcpNonce) {
|
||||
DEBUG_LOG(("Connection Info: TCP/%1-transport chosen by pq-response").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingTcp;
|
||||
emit connected();
|
||||
}
|
||||
} catch (Exception &e) {
|
||||
DEBUG_LOG(("Connection Error: exception in parsing TCP fake pq-responce, %1").arg(e.what()));
|
||||
emit error();
|
||||
}
|
||||
}
|
||||
|
||||
receivedQueue.push_back(data);
|
||||
emit receivedData();
|
||||
}
|
||||
|
||||
bool MTPtcpConnection::isConnected() {
|
||||
return sock.state() == QAbstractSocket::ConnectedState;
|
||||
bool MTPtcpConnection::isConnected() const {
|
||||
return (status == UsingTcp);
|
||||
}
|
||||
|
||||
int32 MTPtcpConnection::debugState() const {
|
||||
@@ -969,21 +1044,25 @@ int32 MTPtcpConnection::debugState() const {
|
||||
}
|
||||
|
||||
QString MTPtcpConnection::transport() const {
|
||||
return qsl("TCP");
|
||||
return isConnected() ? qsl("TCP") : QString();
|
||||
}
|
||||
|
||||
void MTPtcpConnection::socketError(QAbstractSocket::SocketError e) {
|
||||
if (status == FinishedWork) return;
|
||||
|
||||
_handleTcpError(e, sock);
|
||||
emit error();
|
||||
}
|
||||
|
||||
MTPhttpConnection::MTPhttpConnection(QThread *thread) {
|
||||
MTPhttpConnection::MTPhttpConnection(QThread *thread) : status(WaitingHttp), httpNonce(MTP::nonce<MTPint128>()), _flags(0) {
|
||||
moveToThread(thread);
|
||||
manager.moveToThread(thread);
|
||||
App::setProxySettings(manager);
|
||||
}
|
||||
|
||||
void MTPhttpConnection::sendData(mtpBuffer &buffer) {
|
||||
if (status == FinishedWork) return;
|
||||
|
||||
if (buffer.size() < 3) {
|
||||
LOG(("TCP Error: writing bad packet, len = %1").arg(buffer.size() * sizeof(mtpPrime)));
|
||||
TCP_LOG(("TCP Error: bad packet %1").arg(mb(&buffer[0], buffer.size() * sizeof(mtpPrime)).str()));
|
||||
@@ -1002,6 +1081,9 @@ void MTPhttpConnection::sendData(mtpBuffer &buffer) {
|
||||
}
|
||||
|
||||
void MTPhttpConnection::disconnectFromServer() {
|
||||
if (status == FinishedWork) return;
|
||||
status = FinishedWork;
|
||||
|
||||
Requests copy = requests;
|
||||
requests.clear();
|
||||
for (Requests::const_iterator i = copy.cbegin(), e = copy.cend(); i != e; ++i) {
|
||||
@@ -1018,14 +1100,23 @@ void MTPhttpConnection::connectToServer(const QString &addr, int32 p, int32 flag
|
||||
address = QUrl(((flags & MTPDdcOption_flag_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport
|
||||
TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString()));
|
||||
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
|
||||
emit connected();
|
||||
|
||||
_flags = flags;
|
||||
|
||||
mtpBuffer buffer(_preparePQFake(httpNonce));
|
||||
|
||||
DEBUG_LOG(("Connection Info: sending fake req_pq through HTTP/%1 transport").arg((flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
|
||||
sendData(buffer);
|
||||
}
|
||||
|
||||
bool MTPhttpConnection::isConnected() {
|
||||
return !address.isEmpty();
|
||||
bool MTPhttpConnection::isConnected() const {
|
||||
return (status == UsingHttp);
|
||||
}
|
||||
|
||||
void MTPhttpConnection::requestFinished(QNetworkReply *reply) {
|
||||
if (status == FinishedWork) return;
|
||||
|
||||
reply->deleteLater();
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
requests.remove(reply);
|
||||
@@ -1034,8 +1125,23 @@ void MTPhttpConnection::requestFinished(QNetworkReply *reply) {
|
||||
if (data.size() == 1) {
|
||||
emit error();
|
||||
} else if (!data.isEmpty()) {
|
||||
receivedQueue.push_back(data);
|
||||
emit receivedData();
|
||||
if (status == UsingHttp) {
|
||||
receivedQueue.push_back(data);
|
||||
emit receivedData();
|
||||
} else {
|
||||
try {
|
||||
MTPResPQ res_pq = _readPQFakeReply(data);
|
||||
const MTPDresPQ &res_pq_data(res_pq.c_resPQ());
|
||||
if (res_pq_data.vnonce == httpNonce) {
|
||||
DEBUG_LOG(("Connection Info: HTTP/%1-transport connected by pq-response").arg((_flags & MTPDdcOption_flag_ipv6) ? "IPv6" : "IPv4"));
|
||||
status = UsingHttp;
|
||||
emit connected();
|
||||
}
|
||||
} catch (Exception &e) {
|
||||
DEBUG_LOG(("Connection Error: exception in parsing HTTP fake pq-responce, %1").arg(e.what()));
|
||||
emit error();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!requests.remove(reply)) {
|
||||
@@ -1061,12 +1167,17 @@ int32 MTPhttpConnection::debugState() const {
|
||||
}
|
||||
|
||||
QString MTPhttpConnection::transport() const {
|
||||
return qsl("HTTP");
|
||||
if (status == UsingHttp) {
|
||||
return qsl("HTTP");
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::createConn(bool createIPv4, bool createIPv6) {
|
||||
destroyConn();
|
||||
if (createIPv4) {
|
||||
QWriteLocker lock(&stateConnMutex);
|
||||
if (cConnectionType() == dbictAuto) {
|
||||
_conn4 = new MTPautoConnection(thread());
|
||||
} else if (cConnectionType() == dbictTcpProxy) {
|
||||
@@ -1078,6 +1189,7 @@ void MTProtoConnectionPrivate::createConn(bool createIPv4, bool createIPv6) {
|
||||
connect(_conn4, SIGNAL(receivedSome()), this, SLOT(onReceivedSome()));
|
||||
}
|
||||
if (createIPv6) {
|
||||
QWriteLocker lock(&stateConnMutex);
|
||||
if (cConnectionType() == dbictAuto) {
|
||||
_conn6 = new MTPautoConnection(thread());
|
||||
} else if (cConnectionType() == dbictTcpProxy) {
|
||||
@@ -1098,14 +1210,23 @@ void MTProtoConnectionPrivate::createConn(bool createIPv4, bool createIPv6) {
|
||||
|
||||
void MTProtoConnectionPrivate::destroyConn(MTPabstractConnection **conn) {
|
||||
if (conn) {
|
||||
if (*conn) {
|
||||
disconnect(*conn, SIGNAL(disconnected()), 0, 0);
|
||||
disconnect(*conn, SIGNAL(receivedData()), 0, 0);
|
||||
disconnect(*conn, SIGNAL(receivedSome()), 0, 0);
|
||||
MTPabstractConnection *toDisconnect = 0;
|
||||
|
||||
(*conn)->disconnectFromServer();
|
||||
(*conn)->deleteLater();
|
||||
*conn = 0;
|
||||
{
|
||||
QWriteLocker lock(&stateConnMutex);
|
||||
if (*conn) {
|
||||
toDisconnect = *conn;
|
||||
disconnect(*conn, SIGNAL(connected()), 0, 0);
|
||||
disconnect(*conn, SIGNAL(disconnected()), 0, 0);
|
||||
disconnect(*conn, SIGNAL(error(bool)), 0, 0);
|
||||
disconnect(*conn, SIGNAL(receivedData()), 0, 0);
|
||||
disconnect(*conn, SIGNAL(receivedSome()), 0, 0);
|
||||
*conn = 0;
|
||||
}
|
||||
}
|
||||
if (toDisconnect) {
|
||||
toDisconnect->disconnectFromServer();
|
||||
toDisconnect->deleteLater();
|
||||
}
|
||||
} else {
|
||||
destroyConn(&_conn4);
|
||||
@@ -1200,7 +1321,7 @@ int32 MTProtoConnectionPrivate::getDC() const {
|
||||
}
|
||||
|
||||
int32 MTProtoConnectionPrivate::getState() const {
|
||||
QReadLocker lock(&stateMutex);
|
||||
QReadLocker lock(&stateConnMutex);
|
||||
int32 result = _state;
|
||||
if (_state < 0) {
|
||||
if (retryTimer.isActive()) {
|
||||
@@ -1214,18 +1335,21 @@ int32 MTProtoConnectionPrivate::getState() const {
|
||||
}
|
||||
|
||||
QString MTProtoConnectionPrivate::transport() const {
|
||||
if ((!_conn4 && !_conn6) || _state < 0) {
|
||||
QReadLocker lock(&stateConnMutex);
|
||||
if ((!_conn4 && !_conn6) || (_conn4 && _conn6) || (_state < 0)) {
|
||||
return QString();
|
||||
}
|
||||
return (_conn4 ? _conn4 : _conn6)->transport();
|
||||
QString result = (_conn4 ? _conn4 : _conn6)->transport();
|
||||
if (!result.isEmpty() && cTryIPv6()) result += (_conn4 ? "/IPv4" : "/IPv6");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MTProtoConnectionPrivate::setState(int32 state, int32 ifState) {
|
||||
if (ifState != MTProtoConnection::UpdateAlways) {
|
||||
QReadLocker lock(&stateMutex);
|
||||
QReadLocker lock(&stateConnMutex);
|
||||
if (_state != ifState) return false;
|
||||
}
|
||||
QWriteLocker lock(&stateMutex);
|
||||
QWriteLocker lock(&stateConnMutex);
|
||||
if (_state == state) return false;
|
||||
_state = state;
|
||||
if (state < 0) {
|
||||
@@ -1784,15 +1908,15 @@ void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
|
||||
port6 = dcIndex6->port;
|
||||
}
|
||||
}
|
||||
bool noIPv4 = (!port4 || ip4.empty()), noIPv6 = (!port6 || ip6.empty());
|
||||
bool noIPv4 = (!port4 || ip4.empty()), noIPv6 = (!cTryIPv6() || !port6 || ip6.empty());
|
||||
if (noIPv4 && noIPv6) {
|
||||
if (afterConfig) {
|
||||
if (noIPv4) LOG(("MTP Error: DC %1 options for IPv4 not found right after config load!").arg(dc));
|
||||
if (noIPv6) LOG(("MTP Error: DC %1 options for IPv6 not found right after config load!").arg(dc));
|
||||
if (cTryIPv6() && noIPv6) LOG(("MTP Error: DC %1 options for IPv6 not found right after config load!").arg(dc));
|
||||
return restart();
|
||||
}
|
||||
if (noIPv4) DEBUG_LOG(("MTP Info: DC %1 options for IPv4 not found, waiting for config").arg(dc));
|
||||
if (noIPv6) DEBUG_LOG(("MTP Info: DC %1 options for IPv6 not found, waiting for config").arg(dc));
|
||||
if (cTryIPv6() && noIPv6) DEBUG_LOG(("MTP Info: DC %1 options for IPv6 not found, waiting for config").arg(dc));
|
||||
connect(mtpConfigLoader(), SIGNAL(loaded()), this, SLOT(onConfigLoaded()));
|
||||
mtpConfigLoader()->load();
|
||||
return;
|
||||
@@ -2916,7 +3040,7 @@ void MTProtoConnectionPrivate::onConnected6() {
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (!sessionData) return;
|
||||
|
||||
disconnect(_conn6, SIGNAL(connected()), this, SLOT(onConnected()));
|
||||
disconnect(_conn6, SIGNAL(connected()), this, SLOT(onConnected6()));
|
||||
if (!_conn6->isConnected()) {
|
||||
LOG(("Connection Error: not connected in onConnected(), state: %1").arg(_conn6->debugState()));
|
||||
return restart();
|
||||
@@ -3479,7 +3603,7 @@ void MTProtoConnectionPrivate::sendRequestNotSecure(const TRequest &request) {
|
||||
|
||||
onSentSome(buffer.size() * sizeof(mtpPrime));
|
||||
|
||||
} catch(Exception &e) {
|
||||
} catch (Exception &e) {
|
||||
return restart();
|
||||
}
|
||||
}
|
||||
@@ -3516,7 +3640,7 @@ bool MTProtoConnectionPrivate::readResponseNotSecure(TResponse &response) {
|
||||
}
|
||||
const mtpPrime *from(answer + 5), *end(from + len - 5);
|
||||
response.read(from, end);
|
||||
} catch(Exception &e) {
|
||||
} catch (Exception &e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -43,7 +43,12 @@ enum {
|
||||
MTPDreplyKeyboardMarkup_flag_single_use = (1 << 1),
|
||||
MTPDreplyKeyboardMarkup_flag_personal = (1 << 2),
|
||||
MTPDreplyKeyboardMarkup_flag_FORCE_REPLY = (1 << 30), // client side flag for forceReply
|
||||
MTPDreplyKeyboardMarkup_flag_ZERO = (1 << 31) // client side flag for zeroMarkup
|
||||
MTPDreplyKeyboardMarkup_flag_ZERO = (1 << 31), // client side flag for zeroMarkup
|
||||
|
||||
MTPDstickerSet_flag_installed = (1 << 0),
|
||||
MTPDstickerSet_flag_disabled = (1 << 1),
|
||||
MTPDstickerSet_flag_official = (1 << 2),
|
||||
MTPDstickerSet_flag_NOT_LOADED = (1 << 31), // client side flag for not yet loaded set
|
||||
};
|
||||
|
||||
static const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_int(0), MTP_vector<MTPKeyboardButtonRow>(0));
|
||||
@@ -141,7 +146,7 @@ public:
|
||||
virtual void sendData(mtpBuffer &buffer) = 0; // has size + 3, buffer[0] = len, buffer[1] = packetnum, buffer[last] = crc32
|
||||
virtual void disconnectFromServer() = 0;
|
||||
virtual void connectToServer(const QString &addr, int32 port, int32 flags) = 0;
|
||||
virtual bool isConnected() = 0;
|
||||
virtual bool isConnected() const = 0;
|
||||
virtual bool usingHttpWait() {
|
||||
return false;
|
||||
}
|
||||
@@ -209,7 +214,7 @@ public:
|
||||
void sendData(mtpBuffer &buffer);
|
||||
void disconnectFromServer();
|
||||
void connectToServer(const QString &addr, int32 port, int32 flags);
|
||||
bool isConnected();
|
||||
bool isConnected() const;
|
||||
bool usingHttpWait();
|
||||
bool needHttpWait();
|
||||
|
||||
@@ -256,7 +261,7 @@ private:
|
||||
Requests requests;
|
||||
|
||||
QString _addr;
|
||||
int32 _port, _tcpTimeout;
|
||||
int32 _port, _tcpTimeout, _flags;
|
||||
QTimer tcpTimeoutTimer;
|
||||
|
||||
};
|
||||
@@ -271,7 +276,7 @@ public:
|
||||
void sendData(mtpBuffer &buffer);
|
||||
void disconnectFromServer();
|
||||
void connectToServer(const QString &addr, int32 port, int32 flags);
|
||||
bool isConnected();
|
||||
bool isConnected() const;
|
||||
|
||||
int32 debugState() const;
|
||||
|
||||
@@ -281,10 +286,29 @@ public slots:
|
||||
|
||||
void socketError(QAbstractSocket::SocketError e);
|
||||
|
||||
void onSocketConnected();
|
||||
void onSocketDisconnected();
|
||||
|
||||
void onTcpTimeoutTimer();
|
||||
|
||||
protected:
|
||||
|
||||
void socketPacket(mtpPrime *packet, uint32 packetSize);
|
||||
|
||||
private:
|
||||
|
||||
enum Status {
|
||||
WaitingTcp = 0,
|
||||
UsingTcp,
|
||||
FinishedWork
|
||||
};
|
||||
Status status;
|
||||
MTPint128 tcpNonce;
|
||||
|
||||
QString _addr;
|
||||
int32 _port, _tcpTimeout, _flags;
|
||||
QTimer tcpTimeoutTimer;
|
||||
|
||||
};
|
||||
|
||||
class MTPhttpConnection : public MTPabstractConnection {
|
||||
@@ -297,7 +321,7 @@ public:
|
||||
void sendData(mtpBuffer &buffer);
|
||||
void disconnectFromServer();
|
||||
void connectToServer(const QString &addr, int32 port, int32 flags);
|
||||
bool isConnected();
|
||||
bool isConnected() const;
|
||||
bool usingHttpWait();
|
||||
bool needHttpWait();
|
||||
|
||||
@@ -311,6 +335,15 @@ public slots:
|
||||
|
||||
private:
|
||||
|
||||
enum Status {
|
||||
WaitingHttp = 0,
|
||||
UsingHttp,
|
||||
FinishedWork
|
||||
};
|
||||
Status status;
|
||||
MTPint128 httpNonce;
|
||||
int32 _flags;
|
||||
|
||||
QNetworkAccessManager manager;
|
||||
QUrl address;
|
||||
|
||||
@@ -414,7 +447,7 @@ private:
|
||||
void clearMessages();
|
||||
|
||||
bool setState(int32 state, int32 ifState = MTProtoConnection::UpdateAlways);
|
||||
mutable QReadWriteLock stateMutex;
|
||||
mutable QReadWriteLock stateConnMutex;
|
||||
int32 _state;
|
||||
|
||||
bool _needSessionReset;
|
||||
|
||||
@@ -366,7 +366,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||
mtpc_invokeWithLayer17,
|
||||
mtpc_invokeWithLayer18,
|
||||
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||
static const mtpPrime mtpCurrentLayer = 31;
|
||||
static const mtpPrime mtpCurrentLayer = 32;
|
||||
|
||||
template <typename bareT>
|
||||
class MTPBoxed : public bareT {
|
||||
|
||||
@@ -3887,6 +3887,8 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" performer: "); ++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;
|
||||
}
|
||||
break;
|
||||
@@ -3949,9 +3951,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
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 1: to.add(" packs: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" sets: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" documents: "); ++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;
|
||||
}
|
||||
break;
|
||||
@@ -4262,10 +4262,13 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" short_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" short_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: 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;
|
||||
}
|
||||
break;
|
||||
@@ -4885,6 +4888,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
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;
|
||||
case 1: to.add(" disabled: "); ++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;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -338,13 +338,13 @@ enum {
|
||||
mtpc_documentAttributeAnimated = 0x11b58939,
|
||||
mtpc_documentAttributeSticker = 0x3a556302,
|
||||
mtpc_documentAttributeVideo = 0x5910cccb,
|
||||
mtpc_documentAttributeAudio = 0x51448e5,
|
||||
mtpc_documentAttributeAudio = 0xded218e0,
|
||||
mtpc_documentAttributeFilename = 0x15590068,
|
||||
mtpc_messages_stickersNotModified = 0xf1749a22,
|
||||
mtpc_messages_stickers = 0x8a8ecd32,
|
||||
mtpc_stickerPack = 0x12b299d4,
|
||||
mtpc_messages_allStickersNotModified = 0xe86602c3,
|
||||
mtpc_messages_allStickers = 0x5ce352ec,
|
||||
mtpc_messages_allStickers = 0xd51dafdb,
|
||||
mtpc_disabledFeature = 0xae636f24,
|
||||
mtpc_updateReadHistoryInbox = 0x9961fd5c,
|
||||
mtpc_updateReadHistoryOutbox = 0x2f2f21bf,
|
||||
@@ -377,7 +377,7 @@ enum {
|
||||
mtpc_inputStickerSetEmpty = 0xffb62b95,
|
||||
mtpc_inputStickerSetID = 0x9de7a269,
|
||||
mtpc_inputStickerSetShortName = 0x861cc8a0,
|
||||
mtpc_stickerSet = 0xa7a43b17,
|
||||
mtpc_stickerSet = 0xcd303b41,
|
||||
mtpc_messages_stickerSet = 0xb60a24a6,
|
||||
mtpc_user = 0x22e49072,
|
||||
mtpc_botCommand = 0xc27ac8c7,
|
||||
@@ -513,7 +513,7 @@ enum {
|
||||
mtpc_messages_checkChatInvite = 0x3eadb1bb,
|
||||
mtpc_messages_importChatInvite = 0x6c50051c,
|
||||
mtpc_messages_getStickerSet = 0x2619a90e,
|
||||
mtpc_messages_installStickerSet = 0xefbbfae9,
|
||||
mtpc_messages_installStickerSet = 0x7b30c3a6,
|
||||
mtpc_messages_uninstallStickerSet = 0xf96e55de,
|
||||
mtpc_messages_startBot = 0x1b3e0ffc
|
||||
};
|
||||
@@ -7146,7 +7146,7 @@ private:
|
||||
friend MTPdocumentAttribute MTP_documentAttributeAnimated();
|
||||
friend MTPdocumentAttribute MTP_documentAttributeSticker(const MTPstring &_alt, const MTPInputStickerSet &_stickerset);
|
||||
friend MTPdocumentAttribute MTP_documentAttributeVideo(MTPint _duration, MTPint _w, MTPint _h);
|
||||
friend MTPdocumentAttribute MTP_documentAttributeAudio(MTPint _duration);
|
||||
friend MTPdocumentAttribute MTP_documentAttributeAudio(MTPint _duration, const MTPstring &_title, const MTPstring &_performer);
|
||||
friend MTPdocumentAttribute MTP_documentAttributeFilename(const MTPstring &_file_name);
|
||||
|
||||
mtpTypeId _type;
|
||||
@@ -7254,7 +7254,7 @@ private:
|
||||
explicit MTPmessages_allStickers(MTPDmessages_allStickers *_data);
|
||||
|
||||
friend MTPmessages_allStickers MTP_messages_allStickersNotModified();
|
||||
friend MTPmessages_allStickers MTP_messages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerPack> &_packs, const MTPVector<MTPStickerSet> &_sets, const MTPVector<MTPDocument> &_documents);
|
||||
friend MTPmessages_allStickers MTP_messages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerSet> &_sets);
|
||||
|
||||
mtpTypeId _type;
|
||||
};
|
||||
@@ -7819,7 +7819,7 @@ public:
|
||||
private:
|
||||
explicit MTPstickerSet(MTPDstickerSet *_data);
|
||||
|
||||
friend MTPstickerSet MTP_stickerSet(const MTPlong &_id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_short_name);
|
||||
friend MTPstickerSet MTP_stickerSet(MTPint _flags, const MTPlong &_id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_short_name, MTPint _count, MTPint _hash);
|
||||
};
|
||||
typedef MTPBoxed<MTPstickerSet> MTPStickerSet;
|
||||
|
||||
@@ -10916,10 +10916,12 @@ class MTPDdocumentAttributeAudio : public mtpDataImpl<MTPDdocumentAttributeAudio
|
||||
public:
|
||||
MTPDdocumentAttributeAudio() {
|
||||
}
|
||||
MTPDdocumentAttributeAudio(MTPint _duration) : vduration(_duration) {
|
||||
MTPDdocumentAttributeAudio(MTPint _duration, const MTPstring &_title, const MTPstring &_performer) : vduration(_duration), vtitle(_title), vperformer(_performer) {
|
||||
}
|
||||
|
||||
MTPint vduration;
|
||||
MTPstring vtitle;
|
||||
MTPstring vperformer;
|
||||
};
|
||||
|
||||
class MTPDdocumentAttributeFilename : public mtpDataImpl<MTPDdocumentAttributeFilename> {
|
||||
@@ -10958,13 +10960,11 @@ class MTPDmessages_allStickers : public mtpDataImpl<MTPDmessages_allStickers> {
|
||||
public:
|
||||
MTPDmessages_allStickers() {
|
||||
}
|
||||
MTPDmessages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerPack> &_packs, const MTPVector<MTPStickerSet> &_sets, const MTPVector<MTPDocument> &_documents) : vhash(_hash), vpacks(_packs), vsets(_sets), vdocuments(_documents) {
|
||||
MTPDmessages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerSet> &_sets) : vhash(_hash), vsets(_sets) {
|
||||
}
|
||||
|
||||
MTPstring vhash;
|
||||
MTPVector<MTPStickerPack> vpacks;
|
||||
MTPVector<MTPStickerSet> vsets;
|
||||
MTPVector<MTPDocument> vdocuments;
|
||||
};
|
||||
|
||||
class MTPDdisabledFeature : public mtpDataImpl<MTPDdisabledFeature> {
|
||||
@@ -11229,13 +11229,16 @@ class MTPDstickerSet : public mtpDataImpl<MTPDstickerSet> {
|
||||
public:
|
||||
MTPDstickerSet() {
|
||||
}
|
||||
MTPDstickerSet(const MTPlong &_id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_short_name) : vid(_id), vaccess_hash(_access_hash), vtitle(_title), vshort_name(_short_name) {
|
||||
MTPDstickerSet(MTPint _flags, const MTPlong &_id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_short_name, MTPint _count, MTPint _hash) : vflags(_flags), vid(_id), vaccess_hash(_access_hash), vtitle(_title), vshort_name(_short_name), vcount(_count), vhash(_hash) {
|
||||
}
|
||||
|
||||
MTPint vflags;
|
||||
MTPlong vid;
|
||||
MTPlong vaccess_hash;
|
||||
MTPstring vtitle;
|
||||
MTPstring vshort_name;
|
||||
MTPint vcount;
|
||||
MTPint vhash;
|
||||
};
|
||||
|
||||
class MTPDmessages_stickerSet : public mtpDataImpl<MTPDmessages_stickerSet> {
|
||||
@@ -16920,26 +16923,29 @@ public:
|
||||
class MTPmessages_installStickerSet { // RPC method 'messages.installStickerSet'
|
||||
public:
|
||||
MTPInputStickerSet vstickerset;
|
||||
MTPBool vdisabled;
|
||||
|
||||
MTPmessages_installStickerSet() {
|
||||
}
|
||||
MTPmessages_installStickerSet(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_installStickerSet) {
|
||||
read(from, end, cons);
|
||||
}
|
||||
MTPmessages_installStickerSet(const MTPInputStickerSet &_stickerset) : vstickerset(_stickerset) {
|
||||
MTPmessages_installStickerSet(const MTPInputStickerSet &_stickerset, MTPBool _disabled) : vstickerset(_stickerset), vdisabled(_disabled) {
|
||||
}
|
||||
|
||||
uint32 innerLength() const {
|
||||
return vstickerset.innerLength();
|
||||
return vstickerset.innerLength() + vdisabled.innerLength();
|
||||
}
|
||||
mtpTypeId type() const {
|
||||
return mtpc_messages_installStickerSet;
|
||||
}
|
||||
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_installStickerSet) {
|
||||
vstickerset.read(from, end);
|
||||
vdisabled.read(from, end);
|
||||
}
|
||||
void write(mtpBuffer &to) const {
|
||||
vstickerset.write(to);
|
||||
vdisabled.write(to);
|
||||
}
|
||||
|
||||
typedef MTPBool ResponseType;
|
||||
@@ -16952,7 +16958,7 @@ public:
|
||||
}
|
||||
MTPmessages_InstallStickerSet(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTPmessages_installStickerSet>(from, end, cons) {
|
||||
}
|
||||
MTPmessages_InstallStickerSet(const MTPInputStickerSet &_stickerset) : MTPBoxed<MTPmessages_installStickerSet>(MTPmessages_installStickerSet(_stickerset)) {
|
||||
MTPmessages_InstallStickerSet(const MTPInputStickerSet &_stickerset, MTPBool _disabled) : MTPBoxed<MTPmessages_installStickerSet>(MTPmessages_installStickerSet(_stickerset, _disabled)) {
|
||||
}
|
||||
};
|
||||
|
||||
@@ -24857,7 +24863,7 @@ inline uint32 MTPdocumentAttribute::innerLength() const {
|
||||
}
|
||||
case mtpc_documentAttributeAudio: {
|
||||
const MTPDdocumentAttributeAudio &v(c_documentAttributeAudio());
|
||||
return v.vduration.innerLength();
|
||||
return v.vduration.innerLength() + v.vtitle.innerLength() + v.vperformer.innerLength();
|
||||
}
|
||||
case mtpc_documentAttributeFilename: {
|
||||
const MTPDdocumentAttributeFilename &v(c_documentAttributeFilename());
|
||||
@@ -24897,6 +24903,8 @@ inline void MTPdocumentAttribute::read(const mtpPrime *&from, const mtpPrime *en
|
||||
if (!data) setData(new MTPDdocumentAttributeAudio());
|
||||
MTPDdocumentAttributeAudio &v(_documentAttributeAudio());
|
||||
v.vduration.read(from, end);
|
||||
v.vtitle.read(from, end);
|
||||
v.vperformer.read(from, end);
|
||||
} break;
|
||||
case mtpc_documentAttributeFilename: _type = cons; {
|
||||
if (!data) setData(new MTPDdocumentAttributeFilename());
|
||||
@@ -24927,6 +24935,8 @@ inline void MTPdocumentAttribute::write(mtpBuffer &to) const {
|
||||
case mtpc_documentAttributeAudio: {
|
||||
const MTPDdocumentAttributeAudio &v(c_documentAttributeAudio());
|
||||
v.vduration.write(to);
|
||||
v.vtitle.write(to);
|
||||
v.vperformer.write(to);
|
||||
} break;
|
||||
case mtpc_documentAttributeFilename: {
|
||||
const MTPDdocumentAttributeFilename &v(c_documentAttributeFilename());
|
||||
@@ -24967,8 +24977,8 @@ inline MTPdocumentAttribute MTP_documentAttributeSticker(const MTPstring &_alt,
|
||||
inline MTPdocumentAttribute MTP_documentAttributeVideo(MTPint _duration, MTPint _w, MTPint _h) {
|
||||
return MTPdocumentAttribute(new MTPDdocumentAttributeVideo(_duration, _w, _h));
|
||||
}
|
||||
inline MTPdocumentAttribute MTP_documentAttributeAudio(MTPint _duration) {
|
||||
return MTPdocumentAttribute(new MTPDdocumentAttributeAudio(_duration));
|
||||
inline MTPdocumentAttribute MTP_documentAttributeAudio(MTPint _duration, const MTPstring &_title, const MTPstring &_performer) {
|
||||
return MTPdocumentAttribute(new MTPDdocumentAttributeAudio(_duration, _title, _performer));
|
||||
}
|
||||
inline MTPdocumentAttribute MTP_documentAttributeFilename(const MTPstring &_file_name) {
|
||||
return MTPdocumentAttribute(new MTPDdocumentAttributeFilename(_file_name));
|
||||
@@ -25058,7 +25068,7 @@ inline uint32 MTPmessages_allStickers::innerLength() const {
|
||||
switch (_type) {
|
||||
case mtpc_messages_allStickers: {
|
||||
const MTPDmessages_allStickers &v(c_messages_allStickers());
|
||||
return v.vhash.innerLength() + v.vpacks.innerLength() + v.vsets.innerLength() + v.vdocuments.innerLength();
|
||||
return v.vhash.innerLength() + v.vsets.innerLength();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -25075,9 +25085,7 @@ inline void MTPmessages_allStickers::read(const mtpPrime *&from, const mtpPrime
|
||||
if (!data) setData(new MTPDmessages_allStickers());
|
||||
MTPDmessages_allStickers &v(_messages_allStickers());
|
||||
v.vhash.read(from, end);
|
||||
v.vpacks.read(from, end);
|
||||
v.vsets.read(from, end);
|
||||
v.vdocuments.read(from, end);
|
||||
} break;
|
||||
default: throw mtpErrorUnexpected(cons, "MTPmessages_allStickers");
|
||||
}
|
||||
@@ -25087,9 +25095,7 @@ inline void MTPmessages_allStickers::write(mtpBuffer &to) const {
|
||||
case mtpc_messages_allStickers: {
|
||||
const MTPDmessages_allStickers &v(c_messages_allStickers());
|
||||
v.vhash.write(to);
|
||||
v.vpacks.write(to);
|
||||
v.vsets.write(to);
|
||||
v.vdocuments.write(to);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -25105,8 +25111,8 @@ inline MTPmessages_allStickers::MTPmessages_allStickers(MTPDmessages_allStickers
|
||||
inline MTPmessages_allStickers MTP_messages_allStickersNotModified() {
|
||||
return MTPmessages_allStickers(mtpc_messages_allStickersNotModified);
|
||||
}
|
||||
inline MTPmessages_allStickers MTP_messages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerPack> &_packs, const MTPVector<MTPStickerSet> &_sets, const MTPVector<MTPDocument> &_documents) {
|
||||
return MTPmessages_allStickers(new MTPDmessages_allStickers(_hash, _packs, _sets, _documents));
|
||||
inline MTPmessages_allStickers MTP_messages_allStickers(const MTPstring &_hash, const MTPVector<MTPStickerSet> &_sets) {
|
||||
return MTPmessages_allStickers(new MTPDmessages_allStickers(_hash, _sets));
|
||||
}
|
||||
|
||||
inline MTPdisabledFeature::MTPdisabledFeature() : mtpDataOwner(new MTPDdisabledFeature()) {
|
||||
@@ -25777,7 +25783,7 @@ inline MTPstickerSet::MTPstickerSet() : mtpDataOwner(new MTPDstickerSet()) {
|
||||
|
||||
inline uint32 MTPstickerSet::innerLength() const {
|
||||
const MTPDstickerSet &v(c_stickerSet());
|
||||
return v.vid.innerLength() + v.vaccess_hash.innerLength() + v.vtitle.innerLength() + v.vshort_name.innerLength();
|
||||
return v.vflags.innerLength() + v.vid.innerLength() + v.vaccess_hash.innerLength() + v.vtitle.innerLength() + v.vshort_name.innerLength() + v.vcount.innerLength() + v.vhash.innerLength();
|
||||
}
|
||||
inline mtpTypeId MTPstickerSet::type() const {
|
||||
return mtpc_stickerSet;
|
||||
@@ -25787,22 +25793,28 @@ inline void MTPstickerSet::read(const mtpPrime *&from, const mtpPrime *end, mtpT
|
||||
|
||||
if (!data) setData(new MTPDstickerSet());
|
||||
MTPDstickerSet &v(_stickerSet());
|
||||
v.vflags.read(from, end);
|
||||
v.vid.read(from, end);
|
||||
v.vaccess_hash.read(from, end);
|
||||
v.vtitle.read(from, end);
|
||||
v.vshort_name.read(from, end);
|
||||
v.vcount.read(from, end);
|
||||
v.vhash.read(from, end);
|
||||
}
|
||||
inline void MTPstickerSet::write(mtpBuffer &to) const {
|
||||
const MTPDstickerSet &v(c_stickerSet());
|
||||
v.vflags.write(to);
|
||||
v.vid.write(to);
|
||||
v.vaccess_hash.write(to);
|
||||
v.vtitle.write(to);
|
||||
v.vshort_name.write(to);
|
||||
v.vcount.write(to);
|
||||
v.vhash.write(to);
|
||||
}
|
||||
inline MTPstickerSet::MTPstickerSet(MTPDstickerSet *_data) : mtpDataOwner(_data) {
|
||||
}
|
||||
inline MTPstickerSet MTP_stickerSet(const MTPlong &_id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_short_name) {
|
||||
return MTPstickerSet(new MTPDstickerSet(_id, _access_hash, _title, _short_name));
|
||||
inline MTPstickerSet MTP_stickerSet(MTPint _flags, const MTPlong &_id, const MTPlong &_access_hash, const MTPstring &_title, const MTPstring &_short_name, MTPint _count, MTPint _hash) {
|
||||
return MTPstickerSet(new MTPDstickerSet(_flags, _id, _access_hash, _title, _short_name, _count, _hash));
|
||||
}
|
||||
|
||||
inline MTPmessages_stickerSet::MTPmessages_stickerSet() : mtpDataOwner(new MTPDmessages_stickerSet()) {
|
||||
|
||||
@@ -524,7 +524,7 @@ documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||
documentAttributeSticker#3a556302 alt:string stickerset:InputStickerSet = DocumentAttribute;
|
||||
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeAudio#51448e5 duration:int = DocumentAttribute;
|
||||
documentAttributeAudio#ded218e0 duration:int title:string performer:string = DocumentAttribute;
|
||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||
|
||||
messages.stickersNotModified#f1749a22 = messages.Stickers;
|
||||
@@ -533,7 +533,7 @@ messages.stickers#8a8ecd32 hash:string stickers:Vector<Document> = messages.Stic
|
||||
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
||||
|
||||
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
||||
messages.allStickers#5ce352ec hash:string packs:Vector<StickerPack> sets:Vector<StickerSet> documents:Vector<Document> = messages.AllStickers;
|
||||
messages.allStickers#d51dafdb hash:string sets:Vector<StickerSet> = messages.AllStickers;
|
||||
|
||||
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
|
||||
|
||||
@@ -588,7 +588,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
|
||||
stickerSet#a7a43b17 id:long access_hash:long title:string short_name:string = StickerSet;
|
||||
stickerSet#cd303b41 flags:# id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
|
||||
@@ -767,6 +767,6 @@ messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
||||
messages.importChatInvite#6c50051c hash:string = Updates;
|
||||
messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
|
||||
messages.installStickerSet#efbbfae9 stickerset:InputStickerSet = Bool;
|
||||
messages.installStickerSet#7b30c3a6 stickerset:InputStickerSet disabled:Bool = Bool;
|
||||
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
|
||||
messages.startBot#1b3e0ffc bot:InputUser chat_id:int random_id:long start_param:string = Updates;
|
||||
|
||||
@@ -40,13 +40,16 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const
|
||||
, _photosInRow(1)
|
||||
, _photosToAdd(0)
|
||||
, _selMode(false)
|
||||
, _width(0)
|
||||
, _audioLeft(st::msgMargin.left())
|
||||
, _audioWidth(st::msgMinWidth)
|
||||
, _audioHeight(st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom())
|
||||
, _width(st::wndMinWidth)
|
||||
, _height(0)
|
||||
, _minHeight(0)
|
||||
, _addToY(0)
|
||||
, _cursor(style::cur_default)
|
||||
, _dragAction(NoDrag)
|
||||
, _dragItem(0)
|
||||
, _dragItem(0), _selectedMsgId(0)
|
||||
, _dragItemIndex(-1)
|
||||
, _mousedItem(0)
|
||||
, _mousedItemIndex(-1)
|
||||
@@ -65,6 +68,8 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const
|
||||
, _touchTime(0)
|
||||
, _menu(0) {
|
||||
|
||||
resize(_width, height());
|
||||
|
||||
App::contextItem(0);
|
||||
|
||||
_touchSelectTimer.setSingleShot(true);
|
||||
@@ -75,6 +80,10 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const
|
||||
|
||||
mediaOverviewUpdated();
|
||||
setMouseTracking(true);
|
||||
|
||||
if (_type == OverviewAudioDocuments) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool OverviewInner::event(QEvent *e) {
|
||||
@@ -131,7 +140,7 @@ void OverviewInner::touchUpdateSpeed() {
|
||||
void OverviewInner::fixItemIndex(int32 ¤t, MsgId msgId) const {
|
||||
if (!msgId) {
|
||||
current = -1;
|
||||
} else if (_type == OverviewPhotos) {
|
||||
} else if (_type == OverviewPhotos || _type == OverviewAudioDocuments) {
|
||||
int32 l = _hist->_overview[_type].size();
|
||||
if (current < 0 || current >= l || _hist->_overview[_type][current] != msgId) {
|
||||
current = -1;
|
||||
@@ -164,6 +173,10 @@ bool OverviewInner::itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) con
|
||||
if (x >= 0 && x < _vsize && y >= 0 && y < _vsize) {
|
||||
return true;
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (x >= _audioLeft && x < _audioLeft + _audioWidth && y >= 0 && y < _audioHeight) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
HistoryItem *item = App::histItemById(msgId);
|
||||
HistoryMedia *media = item ? item->getMedia(true) : 0;
|
||||
@@ -183,6 +196,8 @@ bool OverviewInner::itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) con
|
||||
int32 OverviewInner::itemHeight(MsgId msgId, int32 index) const {
|
||||
if (_type == OverviewPhotos) {
|
||||
return _vsize;
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
return _audioHeight;
|
||||
}
|
||||
|
||||
fixItemIndex(index, msgId);
|
||||
@@ -198,7 +213,7 @@ void OverviewInner::moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32
|
||||
}
|
||||
|
||||
index += delta;
|
||||
if (_type == OverviewPhotos) {
|
||||
if (_type == OverviewPhotos || _type == OverviewAudioDocuments) {
|
||||
if (index < 0 || index >= _hist->_overview[_type].size()) {
|
||||
msgId = 0;
|
||||
index = -1;
|
||||
@@ -232,6 +247,8 @@ void OverviewInner::updateMsg(MsgId itemId, int32 itemIndex) {
|
||||
int32 vsize = (_vsize + st::overviewPhotoSkip);
|
||||
int32 row = (_photosToAdd + itemIndex) / _photosInRow, col = (_photosToAdd + itemIndex) % _photosInRow;
|
||||
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
update(_audioLeft, _addToY + int32(itemIndex * _audioHeight), _audioWidth, _audioHeight);
|
||||
} else {
|
||||
HistoryItem *item = App::histItemById(itemId);
|
||||
HistoryMedia *media = item ? item->getMedia(true) : 0;
|
||||
@@ -367,12 +384,11 @@ void OverviewInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton but
|
||||
_dragStartPos = mapMouseToItem(mapFromGlobal(screenPos), _dragItem, _dragItemIndex);
|
||||
_dragWasInactive = App::wnd()->inactivePress();
|
||||
if (_dragWasInactive) App::wnd()->inactivePress(false);
|
||||
bool textLink = textlnkDown() && !textlnkDown()->encoded().isEmpty();
|
||||
if (textLink) {
|
||||
if (textlnkDown() && _selected.isEmpty()) {
|
||||
_dragAction = PrepareDrag;
|
||||
} else if (!_selected.isEmpty()) {
|
||||
if (_selected.cbegin().value() == FullItemSel) {
|
||||
if (_selected.constFind(_dragItem) != _selected.cend() && App::hoveredItem()) {
|
||||
if (_selected.constFind(_dragItem) != _selected.cend() && textlnkDown()) {
|
||||
_dragAction = PrepareDrag; // start items drag
|
||||
} else {
|
||||
_dragAction = PrepareSelect; // start items select
|
||||
@@ -382,23 +398,25 @@ void OverviewInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton but
|
||||
if (_dragAction == NoDrag && _dragItem) {
|
||||
bool afterDragSymbol = false , uponSymbol = false;
|
||||
uint16 symbol = 0;
|
||||
if (textlnkDown()) {
|
||||
_dragSymbol = symbol;
|
||||
uint32 selStatus = (_dragSymbol << 16) | _dragSymbol;
|
||||
if (selStatus != FullItemSel && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel)) {
|
||||
if (!_selected.isEmpty()) {
|
||||
updateMsg(_selected.cbegin().key(), -1);
|
||||
_selected.clear();
|
||||
if (!_dragWasInactive) {
|
||||
if (textlnkDown()) {
|
||||
_dragSymbol = symbol;
|
||||
uint32 selStatus = (_dragSymbol << 16) | _dragSymbol;
|
||||
if (selStatus != FullItemSel && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel)) {
|
||||
if (!_selected.isEmpty()) {
|
||||
updateMsg(_selected.cbegin().key(), -1);
|
||||
_selected.clear();
|
||||
}
|
||||
_selected.insert(_dragItem, selStatus);
|
||||
_dragAction = Selecting;
|
||||
updateMsg(_dragItem, _dragItemIndex);
|
||||
_overview->updateTopBarSelection();
|
||||
} else {
|
||||
_dragAction = PrepareSelect;
|
||||
}
|
||||
_selected.insert(_dragItem, selStatus);
|
||||
_dragAction = Selecting;
|
||||
updateMsg(_dragItem, _dragItemIndex);
|
||||
_overview->updateTopBarSelection();
|
||||
} else {
|
||||
_dragAction = PrepareSelect;
|
||||
_dragAction = PrepareSelect; // start items select
|
||||
}
|
||||
} else {
|
||||
_dragAction = PrepareSelect; // start items select
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +479,11 @@ void OverviewInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton bu
|
||||
if (i != _selected.cend() && i.value() == FullItemSel) {
|
||||
_selected.erase(i);
|
||||
updateMsg(_dragItem, _dragItemIndex);
|
||||
} else if (i == _selected.cend() && _dragItem > 0 && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
|
||||
if (_selected.size() < MaxSelectedItems) {
|
||||
_selected.insert(_dragItem, FullItemSel);
|
||||
updateMsg(_dragItem, _dragItemIndex);
|
||||
}
|
||||
} else {
|
||||
_selected.clear();
|
||||
parentWidget()->update();
|
||||
@@ -481,6 +504,73 @@ void OverviewInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton bu
|
||||
_overview->updateTopBarSelection();
|
||||
}
|
||||
|
||||
void OverviewInner::onDragExec() {
|
||||
if (_dragAction != Dragging) return;
|
||||
|
||||
bool uponSelected = false;
|
||||
if (_dragItem) {
|
||||
bool afterDragSymbol;
|
||||
uint16 symbol;
|
||||
if (!_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
|
||||
uponSelected = _selected.contains(_dragItem);
|
||||
} else {
|
||||
uponSelected = false;
|
||||
}
|
||||
}
|
||||
QString sel;
|
||||
QList<QUrl> urls;
|
||||
bool forwardSelected = false;
|
||||
if (uponSelected) {
|
||||
forwardSelected = !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel && cWideMode();
|
||||
} else if (textlnkDown()) {
|
||||
sel = textlnkDown()->encoded();
|
||||
if (!sel.isEmpty() && sel.at(0) != '/' && sel.at(0) != '@' && sel.at(0) != '#') {
|
||||
// urls.push_back(QUrl::fromEncoded(sel.toUtf8())); // Google Chrome crashes in Mac OS X O_o
|
||||
}
|
||||
}
|
||||
if (!sel.isEmpty() || forwardSelected) {
|
||||
updateDragSelection(0, -1, 0, -1, false);
|
||||
_overview->noSelectingScroll();
|
||||
|
||||
QDrag *drag = new QDrag(App::wnd());
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
|
||||
if (!sel.isEmpty()) mimeData->setText(sel);
|
||||
if (!urls.isEmpty()) mimeData->setUrls(urls);
|
||||
if (forwardSelected) {
|
||||
mimeData->setData(qsl("application/x-td-forward-selected"), "1");
|
||||
}
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec(Qt::CopyAction);
|
||||
return;
|
||||
} else {
|
||||
HistoryItem *pressedLnkItem = App::pressedLinkItem(), *pressedItem = App::pressedItem();
|
||||
QLatin1String lnkType = (textlnkDown() && pressedLnkItem) ? textlnkDown()->type() : qstr("");
|
||||
bool lnkPhoto = (lnkType == qstr("PhotoLink")),
|
||||
lnkVideo = (lnkType == qstr("VideoOpenLink")),
|
||||
lnkAudio = (lnkType == qstr("AudioOpenLink")),
|
||||
lnkDocument = (lnkType == qstr("DocumentOpenLink"));
|
||||
if (lnkPhoto || lnkVideo || lnkAudio || lnkDocument) {
|
||||
QDrag *drag = new QDrag(App::wnd());
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
|
||||
mimeData->setData(qsl("application/x-td-forward-pressed-link"), "1");
|
||||
if (lnkDocument) {
|
||||
QString already = static_cast<DocumentOpenLink*>(textlnkDown().data())->document()->already(true);
|
||||
if (!already.isEmpty()) {
|
||||
QList<QUrl> urls;
|
||||
urls.push_back(QUrl::fromLocalFile(already));
|
||||
mimeData->setUrls(urls);
|
||||
}
|
||||
}
|
||||
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec(Qt::CopyAction);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewInner::touchScrollUpdated(const QPoint &screenPos) {
|
||||
_touchPos = screenPos;
|
||||
_overview->touchScroll(_touchPos - _touchPrevPos);
|
||||
@@ -495,7 +585,7 @@ void OverviewInner::applyDragSelection() {
|
||||
}
|
||||
if (_dragSelecting) {
|
||||
for (int32 i = _dragSelToIndex; i <= _dragSelFromIndex; ++i) {
|
||||
MsgId msgid = (_type == OverviewPhotos) ? _hist->_overview[_type][i] : _items[i].msgid;
|
||||
MsgId msgid = (_type == OverviewPhotos || _type == OverviewAudioDocuments) ? _hist->_overview[_type][i] : _items[i].msgid;
|
||||
if (!msgid) continue;
|
||||
|
||||
SelectedItems::iterator j = _selected.find(msgid);
|
||||
@@ -514,7 +604,7 @@ void OverviewInner::applyDragSelection() {
|
||||
}
|
||||
} else {
|
||||
for (int32 i = _dragSelToIndex; i <= _dragSelFromIndex; ++i) {
|
||||
MsgId msgid = (_type == OverviewPhotos) ? _hist->_overview[_type][i] : _items[i].msgid;
|
||||
MsgId msgid = (_type == OverviewPhotos || _type == OverviewAudioDocuments) ? _hist->_overview[_type][i] : _items[i].msgid;
|
||||
if (!msgid) continue;
|
||||
|
||||
SelectedItems::iterator j = _selected.find(msgid);
|
||||
@@ -537,6 +627,8 @@ QPoint OverviewInner::mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex) {
|
||||
float64 w = (_width - st::overviewPhotoSkip) / float64(_photosInRow);
|
||||
p.setX(p.x() - int32(col * w) - st::overviewPhotoSkip);
|
||||
p.setY(p.y() - _addToY - row * (_vsize + st::overviewPhotoSkip) - st::overviewPhotoSkip);
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
p.setY(p.y() - _addToY - itemIndex * _audioHeight);
|
||||
} else {
|
||||
p.setY(p.y() - _addToY - (_height - _items[itemIndex].y));
|
||||
}
|
||||
@@ -547,6 +639,16 @@ void OverviewInner::clear() {
|
||||
_cached.clear();
|
||||
}
|
||||
|
||||
int32 OverviewInner::itemTop(MsgId msgId) const {
|
||||
if (_type == OverviewAudioDocuments) {
|
||||
int32 index = _hist->_overview[_type].indexOf(msgId);
|
||||
if (index >= 0) {
|
||||
return _addToY + int32(index * _audioHeight);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
QPixmap OverviewInner::genPix(PhotoData *photo, int32 size) {
|
||||
size *= cIntRetinaFactor();
|
||||
QImage img = (photo->full->loaded() ? photo->full : (photo->medium->loaded() ? photo->medium : photo->thumb))->pix().toImage();
|
||||
@@ -672,6 +774,32 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
int32 from = int32(r.top() - _addToY) / int32(_audioHeight);
|
||||
int32 to = int32(r.bottom() - _addToY) / int32(_audioHeight) + 1;
|
||||
History::MediaOverview &overview(_hist->_overview[_type]);
|
||||
int32 count = overview.size();
|
||||
p.translate(_audioLeft, _addToY + from * _audioHeight);
|
||||
for (int32 index = from; index < to; ++index) {
|
||||
if (index >= count) break;
|
||||
|
||||
HistoryItem *item = App::histItemById(overview[index]);
|
||||
HistoryMedia *m = item ? item->getMedia(true) : 0;
|
||||
if (!m || m->type() != MediaTypeDocument) continue;
|
||||
|
||||
uint32 sel = 0;
|
||||
if (index >= selfrom && index <= selto) {
|
||||
sel = (_dragSelecting && item->id > 0) ? FullItemSel : 0;
|
||||
} else if (hasSel) {
|
||||
SelectedItems::const_iterator i = _selected.constFind(item->id);
|
||||
if (i != selEnd) {
|
||||
sel = i.value();
|
||||
}
|
||||
}
|
||||
|
||||
static_cast<HistoryDocument*>(m)->drawInPlaylist(p, item, (sel == FullItemSel), ((_menu ? (App::contextItem() ? App::contextItem()->id : 0) : _selectedMsgId) == item->id), _audioWidth);
|
||||
p.translate(0, _audioHeight);
|
||||
}
|
||||
} else {
|
||||
p.translate(0, st::msgMargin.top() + _addToY);
|
||||
int32 y = 0, w = _width - st::msgMargin.left() - st::msgMargin.right();
|
||||
@@ -750,6 +878,7 @@ void OverviewInner::onUpdateSelected() {
|
||||
TextLinkPtr lnk;
|
||||
HistoryItem *item = 0;
|
||||
int32 index = -1;
|
||||
int32 newsel = 0;
|
||||
if (_type == OverviewPhotos) {
|
||||
float64 w = (float64(_width - st::overviewPhotoSkip) / _photosInRow);
|
||||
int32 inRow = int32((m.x() - (st::overviewPhotoSkip / 2)) / w), vsize = (_vsize + st::overviewPhotoSkip);
|
||||
@@ -785,6 +914,43 @@ void OverviewInner::onUpdateSelected() {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
int32 i = int32((m.y() - _addToY) / _audioHeight), count = _hist->_overview[_type].size();
|
||||
if (!count) return;
|
||||
|
||||
bool upon = true;
|
||||
if (m.y() < _addToY) {
|
||||
i = 0;
|
||||
upon = false;
|
||||
}
|
||||
if (i >= count) {
|
||||
i = count - 1;
|
||||
upon = false;
|
||||
}
|
||||
MsgId msgid = _hist->_overview[_type][i];
|
||||
HistoryItem *histItem = App::histItemById(msgid);
|
||||
if (histItem) {
|
||||
item = histItem;
|
||||
index = i;
|
||||
if (upon && m.x() >= _audioLeft && m.x() < _audioLeft + _audioWidth) {
|
||||
HistoryMedia *media = item->getMedia(true);
|
||||
if (media && media->type() == MediaTypeDocument) {
|
||||
lnk = static_cast<HistoryDocument*>(media)->linkInPlaylist();
|
||||
newsel = item->id;
|
||||
}
|
||||
}
|
||||
if (newsel != _selectedMsgId) {
|
||||
updateMsg(App::histItemById(_selectedMsgId));
|
||||
_selectedMsgId = newsel;
|
||||
updateMsg(item);
|
||||
}
|
||||
} else {
|
||||
if (newsel != _selectedMsgId) {
|
||||
updateMsg(App::histItemById(_selectedMsgId));
|
||||
_selectedMsgId = newsel;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int32 w = _width - st::msgMargin.left() - st::msgMargin.right();
|
||||
if (_items.isEmpty()) return;
|
||||
@@ -824,9 +990,9 @@ void OverviewInner::onUpdateSelected() {
|
||||
}
|
||||
left += st::msgPhotoSkip;
|
||||
}
|
||||
bool inText = false;
|
||||
HistoryCursorState cursorState = HistoryDefaultCursorState;
|
||||
TextLinkPtr link;
|
||||
media->getState(link, inText, m.x() - left, m.y() - y - st::msgMargin.top(), item, w);
|
||||
media->getState(link, cursorState, m.x() - left, m.y() - y - st::msgMargin.top(), item, w);
|
||||
if (link) lnk = link;
|
||||
}
|
||||
} else {
|
||||
@@ -841,7 +1007,7 @@ void OverviewInner::onUpdateSelected() {
|
||||
m = mapMouseToItem(m, _mousedItem, _mousedItemIndex);
|
||||
|
||||
Qt::CursorShape cur = style::cur_default;
|
||||
bool inText = false, lnkChanged = false;
|
||||
bool lnkChanged = false;
|
||||
if (lnk != textlnkOver()) {
|
||||
lnkChanged = true;
|
||||
updateMsg(App::hoveredLinkItem());
|
||||
@@ -866,6 +1032,7 @@ void OverviewInner::onUpdateSelected() {
|
||||
if (_mousedItem != _dragItem || (m - _dragStartPos).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
if (_dragAction == PrepareDrag) {
|
||||
_dragAction = Dragging;
|
||||
QTimer::singleShot(1, this, SLOT(onDragExec()));
|
||||
} else if (_dragAction == PrepareSelect) {
|
||||
_dragAction = Selecting;
|
||||
}
|
||||
@@ -878,7 +1045,7 @@ void OverviewInner::onUpdateSelected() {
|
||||
_selected[_dragItem] = 0;
|
||||
updateDragSelection(0, -1, 0, -1, false);
|
||||
} else {
|
||||
bool selectingDown = (_type == OverviewPhotos ? (_mousedItemIndex > _dragItemIndex) : (_mousedItemIndex < _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && (_type == OverviewPhotos ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
|
||||
bool selectingDown = ((_type == OverviewPhotos || _type == OverviewAudioDocuments) ? (_mousedItemIndex > _dragItemIndex) : (_mousedItemIndex < _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && (_type == OverviewPhotos ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
|
||||
MsgId dragSelFrom = _dragItem, dragSelTo = _mousedItem;
|
||||
int32 dragSelFromIndex = _dragItemIndex, dragSelToIndex = _mousedItemIndex;
|
||||
if (!itemHasPoint(dragSelFrom, dragSelFromIndex, _dragStartPos.x(), _dragStartPos.y())) { // maybe exclude dragSelFrom
|
||||
@@ -887,6 +1054,10 @@ void OverviewInner::onUpdateSelected() {
|
||||
if (_dragStartPos.x() >= _vsize || ((_mousedItem == dragSelFrom) && (m.x() < _dragStartPos.x() + QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (_dragStartPos.y() >= itemHeight(dragSelFrom, dragSelFromIndex) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
|
||||
}
|
||||
} else {
|
||||
if (_dragStartPos.y() >= (itemHeight(dragSelFrom, dragSelFromIndex) - st::msgMargin.bottom()) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
|
||||
@@ -897,6 +1068,10 @@ void OverviewInner::onUpdateSelected() {
|
||||
if (_dragStartPos.x() < 0 || ((_mousedItem == dragSelFrom) && (m.x() >= _dragStartPos.x() - QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (_dragStartPos.y() < 0 || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
|
||||
}
|
||||
} else {
|
||||
if (_dragStartPos.y() < st::msgMargin.top() || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
|
||||
@@ -910,6 +1085,10 @@ void OverviewInner::onUpdateSelected() {
|
||||
if (m.x() < 0) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (m.y() < 0) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
}
|
||||
} else {
|
||||
if (m.y() < st::msgMargin.top()) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
@@ -920,6 +1099,10 @@ void OverviewInner::onUpdateSelected() {
|
||||
if (m.x() >= _vsize) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex)) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
}
|
||||
} else {
|
||||
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex) - st::msgMargin.bottom()) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
|
||||
@@ -931,7 +1114,7 @@ void OverviewInner::onUpdateSelected() {
|
||||
MsgId dragFirstAffected = dragSelFrom;
|
||||
int32 dragFirstAffectedIndex = dragSelFromIndex;
|
||||
while (dragFirstAffectedIndex >= 0 && dragFirstAffected <= 0) {
|
||||
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, ((selectingDown && (_type == OverviewPhotos)) || (!selectingDown && (_type != OverviewPhotos))) ? -1 : 1);
|
||||
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, ((selectingDown && (_type == OverviewPhotos || _type == OverviewAudioDocuments)) || (!selectingDown && (_type != OverviewPhotos && _type != OverviewAudioDocuments))) ? -1 : 1);
|
||||
}
|
||||
if (dragFirstAffectedIndex >= 0) {
|
||||
SelectedItems::const_iterator i = _selected.constFind(dragFirstAffected);
|
||||
@@ -1007,6 +1190,10 @@ void OverviewInner::enterEvent(QEvent *e) {
|
||||
}
|
||||
|
||||
void OverviewInner::leaveEvent(QEvent *e) {
|
||||
if (_selectedMsgId > 0) {
|
||||
updateMsg(App::histItemById(_selectedMsgId));
|
||||
_selectedMsgId = 0;
|
||||
}
|
||||
if (textlnkOver()) {
|
||||
updateMsg(App::hoveredLinkItem());
|
||||
textlnkOver(TextLinkPtr());
|
||||
@@ -1021,7 +1208,9 @@ void OverviewInner::leaveEvent(QEvent *e) {
|
||||
|
||||
void OverviewInner::resizeEvent(QResizeEvent *e) {
|
||||
_width = width();
|
||||
showAll();
|
||||
_audioWidth = qMin(_width - st::profilePadding.left() - st::profilePadding.right(), int(st::profileMaxWidth));
|
||||
_audioLeft = (_width - _audioWidth) / 2;
|
||||
showAll(true);
|
||||
onUpdateSelected();
|
||||
update();
|
||||
}
|
||||
@@ -1030,6 +1219,8 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
if (_menu) {
|
||||
_menu->deleteLater();
|
||||
_menu = 0;
|
||||
updateMsg(App::contextItem());
|
||||
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
|
||||
}
|
||||
if (e->reason() == QContextMenuEvent::Mouse) {
|
||||
dragActionUpdate(e->globalPos());
|
||||
@@ -1089,6 +1280,8 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
_menu->addAction(lang(lng_context_select_msg), this, SLOT(selectMessage()))->setEnabled(true);
|
||||
}
|
||||
App::contextItem(App::hoveredLinkItem());
|
||||
updateMsg(App::contextItem());
|
||||
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
|
||||
} else if (App::mousedItem() && App::mousedItem()->id == _mousedItem) {
|
||||
_menu = new ContextMenu(_overview);
|
||||
_menu->addAction(lang(lng_context_to_msg), this, SLOT(goToMessage()))->setEnabled(true);
|
||||
@@ -1106,6 +1299,8 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
_menu->addAction(lang(lng_context_select_msg), this, SLOT(selectMessage()))->setEnabled(true);
|
||||
}
|
||||
App::contextItem(App::mousedItem());
|
||||
updateMsg(App::contextItem());
|
||||
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
|
||||
}
|
||||
if (_menu) {
|
||||
_menu->deleteOnHide();
|
||||
@@ -1118,7 +1313,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeight) {
|
||||
if (width() == nwidth && minHeight == _minHeight) return scrollTop;
|
||||
_minHeight = minHeight;
|
||||
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
|
||||
_addToY = (_type == OverviewAudioDocuments) ? st::playlistPadding : ((_height < _minHeight) ? (_minHeight - _height) : 0);
|
||||
if (_type == OverviewPhotos && _resizeIndex < 0) {
|
||||
_resizeIndex = _photosInRow * ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) + _photosInRow - 1;
|
||||
_resizeSkip = (scrollTop + minHeight) - ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) * int32(_vsize + st::overviewPhotoSkip);
|
||||
@@ -1241,6 +1436,8 @@ void OverviewInner::openContextFile() {
|
||||
void OverviewInner::onMenuDestroy(QObject *obj) {
|
||||
if (_menu == obj) {
|
||||
_menu = 0;
|
||||
updateMsg(App::contextItem());
|
||||
if (_selectedMsgId > 0) updateMsg(App::histItemById(_selectedMsgId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1304,14 +1501,15 @@ void OverviewInner::onTouchScrollTimer() {
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewInner::mediaOverviewUpdated() {
|
||||
void OverviewInner::mediaOverviewUpdated(bool fromResize) {
|
||||
int32 oldHeight = _height;
|
||||
if (_type != OverviewPhotos) {
|
||||
if (_type != OverviewPhotos && _type != OverviewAudioDocuments) {
|
||||
History::MediaOverview &o(_hist->_overview[_type]);
|
||||
int32 l = o.size();
|
||||
_items.reserve(2 * l); // day items
|
||||
|
||||
int32 y = 0, in = 0;
|
||||
int32 w = _width - st::msgMargin.left() - st::msgMargin.right();
|
||||
bool allGood = true;
|
||||
QDate prevDate;
|
||||
for (int32 i = 0; i < l; ++i) {
|
||||
@@ -1319,14 +1517,36 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||
if (allGood) {
|
||||
if (_items.size() > in && _items.at(in).msgid == msgid) {
|
||||
prevDate = _items.at(in).date;
|
||||
y = _items.at(in).y;
|
||||
if (fromResize) {
|
||||
HistoryItem *item = App::histItemById(msgid);
|
||||
HistoryMedia *media = item ? item->getMedia(true) : 0;
|
||||
if (media) {
|
||||
y += media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom(); // item height
|
||||
}
|
||||
_items[in].y = y;
|
||||
} else {
|
||||
y = _items.at(in).y;
|
||||
}
|
||||
++in;
|
||||
continue;
|
||||
}
|
||||
if (_items.size() > in + 1 && !_items.at(in).msgid && _items.at(in + 1).msgid == msgid) { // day item
|
||||
if (fromResize) {
|
||||
y += st::msgServiceFont->height + st::msgServicePadding.top() + st::msgServicePadding.bottom() + st::msgServiceMargin.top() + st::msgServiceMargin.bottom(); // day item height
|
||||
_items[in].y = y;
|
||||
}
|
||||
++in;
|
||||
prevDate = _items.at(in).date;
|
||||
y = _items.at(in).y;
|
||||
if (fromResize) {
|
||||
HistoryItem *item = App::histItemById(msgid);
|
||||
HistoryMedia *media = item ? item->getMedia(true) : 0;
|
||||
if (media) {
|
||||
y += media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom(); // item height
|
||||
}
|
||||
_items[in].y = y;
|
||||
} else {
|
||||
y = _items.at(in).y;
|
||||
}
|
||||
++in;
|
||||
continue;
|
||||
}
|
||||
@@ -1353,7 +1573,6 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||
} else {
|
||||
prevDate = date;
|
||||
}
|
||||
int32 w = _width - st::msgMargin.left() - st::msgMargin.right();
|
||||
media->initDimensions(item);
|
||||
y += media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom(); // item height
|
||||
if (_items.size() > in) {
|
||||
@@ -1378,8 +1597,10 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||
}
|
||||
if (_height != y) {
|
||||
_height = y;
|
||||
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
|
||||
resize(width(), _minHeight > _height ? _minHeight : _height);
|
||||
if (!fromResize) {
|
||||
_addToY = (_type == OverviewAudioDocuments) ? st::playlistPadding : ((_height < _minHeight) ? (_minHeight - _height) : 0);
|
||||
resize(width(), _minHeight > _height ? _minHeight : _height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1388,9 +1609,11 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||
fixItemIndex(_mousedItemIndex, _mousedItem);
|
||||
fixItemIndex(_dragItemIndex, _dragItem);
|
||||
|
||||
resizeEvent(0);
|
||||
if (_height != oldHeight) {
|
||||
_overview->scrollBy(_height - oldHeight);
|
||||
if (!fromResize) {
|
||||
resizeEvent(0);
|
||||
if (_height != oldHeight) {
|
||||
_overview->scrollBy(_height - oldHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,7 +1665,7 @@ void OverviewInner::itemRemoved(HistoryItem *item) {
|
||||
}
|
||||
|
||||
void OverviewInner::itemResized(HistoryItem *item, bool scrollToIt) {
|
||||
if (_type != OverviewPhotos) {
|
||||
if (_type != OverviewPhotos && _type != OverviewAudioDocuments) {
|
||||
HistoryMedia *media = item ? item->getMedia(true) : 0;
|
||||
if (!media) return;
|
||||
|
||||
@@ -1460,7 +1683,7 @@ void OverviewInner::itemResized(HistoryItem *item, bool scrollToIt) {
|
||||
_items[j].y += newh;
|
||||
}
|
||||
_height = _items[l - 1].y;
|
||||
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
|
||||
_addToY = (_type == OverviewAudioDocuments) ? st::playlistPadding : ((_height < _minHeight) ? (_minHeight - _height) : 0);
|
||||
resize(width(), _minHeight > _height ? _minHeight : _height);
|
||||
if (scrollToIt) {
|
||||
if (_addToY + _height - from > _scroll->scrollTop() + _scroll->height()) {
|
||||
@@ -1490,6 +1713,11 @@ void OverviewInner::msgUpdated(const HistoryItem *msg) {
|
||||
int32 row = (_photosToAdd + index) / _photosInRow, col = (_photosToAdd + index) % _photosInRow;
|
||||
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
int32 index = _hist->_overview[_type].indexOf(msgid);
|
||||
if (index >= 0) {
|
||||
update(_audioLeft, _addToY + int32(index * _audioHeight), _audioWidth, _audioHeight);
|
||||
}
|
||||
} else {
|
||||
for (int32 i = 0, l = _items.size(); i != l; ++i) {
|
||||
if (_items[i].msgid == msgid) {
|
||||
@@ -1503,7 +1731,7 @@ void OverviewInner::msgUpdated(const HistoryItem *msg) {
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewInner::showAll() {
|
||||
void OverviewInner::showAll(bool recountHeights) {
|
||||
int32 newHeight = height();
|
||||
if (_type == OverviewPhotos) {
|
||||
_photosInRow = int32(width() - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip);
|
||||
@@ -1518,10 +1746,16 @@ void OverviewInner::showAll() {
|
||||
}
|
||||
int32 rows = ((_photosToAdd + count) / _photosInRow) + (((_photosToAdd + count) % _photosInRow) ? 1 : 0);
|
||||
newHeight = _height = (_vsize + st::overviewPhotoSkip) * rows + st::overviewPhotoSkip;
|
||||
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
int32 count = _hist->_overview[_type].size(), fullCount = _hist->_overviewCount[_type];
|
||||
newHeight = _height = count * _audioHeight + 2 * st::playlistPadding;
|
||||
} else {
|
||||
if (recountHeights && _type == OverviewVideos) { // recount heights because of captions
|
||||
mediaOverviewUpdated(true);
|
||||
}
|
||||
newHeight = _height;
|
||||
}
|
||||
_addToY = (_type == OverviewAudioDocuments) ? st::playlistPadding : ((_height < _minHeight) ? (_minHeight - _height) : 0);
|
||||
if (newHeight < _minHeight) {
|
||||
newHeight = _minHeight;
|
||||
}
|
||||
@@ -1531,6 +1765,7 @@ void OverviewInner::showAll() {
|
||||
}
|
||||
|
||||
OverviewInner::~OverviewInner() {
|
||||
_dragAction = NoDrag;
|
||||
}
|
||||
|
||||
OverviewWidget::OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverviewType type) : QWidget(parent)
|
||||
@@ -1555,6 +1790,8 @@ OverviewWidget::OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverv
|
||||
connect(&_scrollTimer, SIGNAL(timeout()), this, SLOT(onScrollTimer()));
|
||||
_scrollTimer.setSingleShot(false);
|
||||
|
||||
connect(App::main()->player(), SIGNAL(playerSongChanged(MsgId)), this, SLOT(onPlayerSongChanged(MsgId)));
|
||||
|
||||
switchType(type);
|
||||
}
|
||||
|
||||
@@ -1575,8 +1812,12 @@ void OverviewWidget::onScroll() {
|
||||
}
|
||||
|
||||
void OverviewWidget::resizeEvent(QResizeEvent *e) {
|
||||
int32 st = _scroll.scrollTop();
|
||||
_scroll.resize(size());
|
||||
int32 newScrollTop = _inner.resizeToWidth(width(), _scroll.scrollTop(), height());
|
||||
int32 newScrollTop = _inner.resizeToWidth(width(), st, height());
|
||||
if (int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0) {
|
||||
newScrollTop += addToY;
|
||||
}
|
||||
if (newScrollTop != _scroll.scrollTop()) {
|
||||
_noDropResizeIndex = true;
|
||||
_scroll.scrollToY(newScrollTop);
|
||||
@@ -1594,33 +1835,36 @@ void OverviewWidget::paintEvent(QPaintEvent *e) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasTopBar = !App::main()->topBar()->isHidden();
|
||||
QRect r(e->rect());
|
||||
if (type() == OverviewPhotos) {
|
||||
if (type() == OverviewPhotos || type() == OverviewAudioDocuments) {
|
||||
p.fillRect(r, st::white->b);
|
||||
} else if (cTileBackground()) {
|
||||
int left = r.left(), top = r.top(), right = r.left() + r.width(), bottom = r.top() + r.height();
|
||||
if (right > 0 && bottom > 0) {
|
||||
QRect fill(left, top + (hasTopBar ? st::topBarHeight : 0), right, bottom + (hasTopBar ? st::topBarHeight : 0));
|
||||
|
||||
if (hasTopBar) p.translate(0, -st::topBarHeight);
|
||||
p.fillRect(fill, QBrush(*cChatBackground()));
|
||||
if (hasTopBar) p.translate(0, st::topBarHeight);
|
||||
}
|
||||
} else {
|
||||
bool hasTopBar = !App::main()->topBar()->isHidden(), hasPlayer = !App::main()->player()->isHidden();
|
||||
QRect fill(0, 0, width(), App::main()->height());
|
||||
int fromy = hasTopBar ? (-st::topBarHeight) : 0, x = 0, y = 0;
|
||||
int fromy = (hasTopBar ? (-st::topBarHeight) : 0) + (hasPlayer ? (-st::playerHeight) : 0), x = 0, y = 0;
|
||||
QPixmap cached = App::main()->cachedBackground(fill, x, y);
|
||||
if (cached.isNull()) {
|
||||
bool smooth = p.renderHints().testFlag(QPainter::SmoothPixmapTransform);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
const QPixmap &pix(*cChatBackground());
|
||||
if (cTileBackground()) {
|
||||
int left = r.left(), top = r.top(), right = r.left() + r.width(), bottom = r.top() + r.height();
|
||||
float64 w = pix.width() / cRetinaFactor(), h = pix.height() / cRetinaFactor();
|
||||
int sx = qFloor(left / w), sy = qFloor((top - fromy) / h), cx = qCeil(right / w), cy = qCeil((bottom - fromy) / h);
|
||||
for (int i = sx; i < cx; ++i) {
|
||||
for (int j = sy; j < cy; ++j) {
|
||||
p.drawPixmap(QPointF(i * w, fromy + j * h), pix);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool smooth = p.renderHints().testFlag(QPainter::SmoothPixmapTransform);
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
QRect to, from;
|
||||
App::main()->backgroundParams(fill, to, from);
|
||||
to.moveTop(to.top() + fromy);
|
||||
p.drawPixmap(to, *cChatBackground(), from);
|
||||
QRect to, from;
|
||||
App::main()->backgroundParams(fill, to, from);
|
||||
to.moveTop(to.top() + fromy);
|
||||
p.drawPixmap(to, pix, from);
|
||||
|
||||
if (!smooth) p.setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||
if (!smooth) p.setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||
}
|
||||
} else {
|
||||
p.drawPixmap(x, fromy + y, cached);
|
||||
}
|
||||
@@ -1654,6 +1898,13 @@ void OverviewWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth)
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewWidget::topBarShadowParams(int32 &x, float64 &o) {
|
||||
if (animating() && a_coord.current() >= 0) {
|
||||
x = a_coord.current();
|
||||
o = a_alpha.current();
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewWidget::topBarClick() {
|
||||
App::main()->showBackFromStack();
|
||||
}
|
||||
@@ -1675,6 +1926,7 @@ void OverviewWidget::switchType(MediaOverviewType type) {
|
||||
case OverviewVideos: _header = lang(lng_profile_videos_header); break;
|
||||
case OverviewDocuments: _header = lang(lng_profile_files_header); break;
|
||||
case OverviewAudios: _header = lang(lng_profile_audios_header); break;
|
||||
case OverviewAudioDocuments: _header = lang(lng_profile_audio_files_header); break;
|
||||
}
|
||||
noSelectingScroll();
|
||||
App::main()->topBar()->showSelected(0);
|
||||
@@ -1706,12 +1958,36 @@ int32 OverviewWidget::lastScrollTop() const {
|
||||
return _scroll.scrollTop();
|
||||
}
|
||||
|
||||
int32 OverviewWidget::countBestScroll() const {
|
||||
if (type() == OverviewAudioDocuments && audioPlayer()) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &playingState);
|
||||
if (playing) {
|
||||
int32 top = _inner.itemTop(playing.msgId);
|
||||
if (top >= 0) {
|
||||
return snap(top - int(_scroll.height() - (st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom())) / 2, 0, _scroll.scrollTopMax());
|
||||
}
|
||||
}
|
||||
}
|
||||
return _scroll.scrollTopMax();
|
||||
}
|
||||
|
||||
void OverviewWidget::fastShow(bool back, int32 lastScrollTop) {
|
||||
stopGif();
|
||||
resizeEvent(0);
|
||||
_scrollSetAfterShow = (lastScrollTop < 0 ? countBestScroll() : lastScrollTop);
|
||||
show();
|
||||
_inner.setFocus();
|
||||
doneShow();
|
||||
}
|
||||
|
||||
void OverviewWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back, int32 lastScrollTop) {
|
||||
stopGif();
|
||||
_bgAnimCache = bgAnimCache;
|
||||
_bgAnimTopBarCache = bgAnimTopBarCache;
|
||||
resizeEvent(0);
|
||||
_scroll.scrollToY(lastScrollTop < 0 ? _scroll.scrollTopMax() : lastScrollTop);
|
||||
_scroll.scrollToY(lastScrollTop < 0 ? countBestScroll() : lastScrollTop);
|
||||
_animCache = myGrab(this, rect());
|
||||
App::main()->topBar()->stopAnim();
|
||||
_animTopBarCache = myGrab(App::main()->topBar(), QRect(0, 0, width(), st::topBarHeight));
|
||||
@@ -1741,10 +2017,7 @@ bool OverviewWidget::animStep(float64 ms) {
|
||||
a_alpha.finish();
|
||||
_bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap();
|
||||
App::main()->topBar()->stopAnim();
|
||||
_scroll.show();
|
||||
_scroll.scrollToY(_scrollSetAfterShow);
|
||||
activate();
|
||||
onScroll();
|
||||
doneShow();
|
||||
} else {
|
||||
a_bgCoord.update(dt1, st::introHideFunc);
|
||||
a_bgAlpha.update(dt1, st::introAlphaHideFunc);
|
||||
@@ -1756,8 +2029,15 @@ bool OverviewWidget::animStep(float64 ms) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void OverviewWidget::mediaOverviewUpdated(PeerData *p) {
|
||||
if (peer() == p) {
|
||||
void OverviewWidget::doneShow() {
|
||||
_scroll.show();
|
||||
_scroll.scrollToY(_scrollSetAfterShow);
|
||||
activate();
|
||||
onScroll();
|
||||
}
|
||||
|
||||
void OverviewWidget::mediaOverviewUpdated(PeerData *p, MediaOverviewType t) {
|
||||
if (peer() == p && t == type()) {
|
||||
_inner.mediaOverviewUpdated();
|
||||
onScroll();
|
||||
updateTopBarSelection();
|
||||
@@ -1825,6 +2105,15 @@ void OverviewWidget::onScrollTimer() {
|
||||
_scroll.scrollToY(_scroll.scrollTop() + d);
|
||||
}
|
||||
|
||||
void OverviewWidget::onPlayerSongChanged(MsgId msgId) {
|
||||
if (type() == OverviewAudioDocuments) {
|
||||
// int32 top = _inner.itemTop(msgId);
|
||||
// if (top > 0) {
|
||||
// _scroll.scrollToY(snap(top - int(_scroll.height() - (st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom())) / 2, 0, _scroll.scrollTopMax()));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewWidget::checkSelectingScroll(QPoint point) {
|
||||
if (point.y() < _scroll.scrollTop()) {
|
||||
_scrollDelta = point.y() - _scroll.scrollTop();
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const PeerData *peer, MediaOverviewType type);
|
||||
|
||||
void clear();
|
||||
int32 itemTop(MsgId msgId) const;
|
||||
|
||||
bool event(QEvent *e);
|
||||
void touchEvent(QTouchEvent *e);
|
||||
@@ -57,7 +58,7 @@ public:
|
||||
|
||||
void setSelectMode(bool enabled);
|
||||
|
||||
void mediaOverviewUpdated();
|
||||
void mediaOverviewUpdated(bool fromResize = false);
|
||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||
void msgUpdated(const HistoryItem *msg);
|
||||
void itemRemoved(HistoryItem *item);
|
||||
@@ -88,6 +89,8 @@ public slots:
|
||||
void onTouchSelect();
|
||||
void onTouchScrollTimer();
|
||||
|
||||
void onDragExec();
|
||||
|
||||
private:
|
||||
|
||||
void fixItemIndex(int32 ¤t, MsgId msgId) const;
|
||||
@@ -107,7 +110,7 @@ private:
|
||||
void applyDragSelection();
|
||||
|
||||
QPixmap genPix(PhotoData *photo, int32 size);
|
||||
void showAll();
|
||||
void showAll(bool recountHeights = false);
|
||||
|
||||
OverviewWidget *_overview;
|
||||
ScrollArea *_scroll;
|
||||
@@ -128,6 +131,9 @@ private:
|
||||
CachedSizes _cached;
|
||||
bool _selMode;
|
||||
|
||||
// audio documents
|
||||
int32 _audioLeft, _audioWidth, _audioHeight;
|
||||
|
||||
// other
|
||||
typedef struct _CachedItem {
|
||||
_CachedItem() : msgid(0), y(0) {
|
||||
@@ -140,6 +146,7 @@ private:
|
||||
} CachedItem;
|
||||
typedef QVector<CachedItem> CachedItems;
|
||||
CachedItems _items;
|
||||
|
||||
int32 _width, _height, _minHeight, _addToY;
|
||||
|
||||
// selection support, like in HistoryWidget
|
||||
@@ -155,7 +162,7 @@ private:
|
||||
};
|
||||
DragAction _dragAction;
|
||||
QPoint _dragStartPos, _dragPos;
|
||||
MsgId _dragItem;
|
||||
MsgId _dragItem, _selectedMsgId;
|
||||
int32 _dragItemIndex;
|
||||
MsgId _mousedItem;
|
||||
int32 _mousedItemIndex;
|
||||
@@ -197,6 +204,7 @@ public:
|
||||
void scrollBy(int32 add);
|
||||
|
||||
void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
|
||||
void topBarShadowParams(int32 &x, float64 &o);
|
||||
void topBarClick();
|
||||
|
||||
PeerData *peer() const;
|
||||
@@ -206,11 +214,15 @@ public:
|
||||
|
||||
int32 lastWidth() const;
|
||||
int32 lastScrollTop() const;
|
||||
int32 countBestScroll() const;
|
||||
|
||||
void fastShow(bool back = false, int32 lastScrollTop = -1);
|
||||
void animShow(const QPixmap &oldAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false, int32 lastScrollTop = -1);
|
||||
bool animStep(float64 ms);
|
||||
|
||||
void mediaOverviewUpdated(PeerData *peer);
|
||||
void doneShow();
|
||||
|
||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||
void msgUpdated(PeerId peer, const HistoryItem *msg);
|
||||
void itemRemoved(HistoryItem *item);
|
||||
@@ -235,6 +247,7 @@ public slots:
|
||||
void onScroll();
|
||||
|
||||
void onScrollTimer();
|
||||
void onPlayerSongChanged(MsgId msgId);
|
||||
|
||||
void onForwardSelected();
|
||||
void onDeleteSelected();
|
||||
|
||||
625
Telegram/SourceFiles/playerwidget.cpp
Normal file
625
Telegram/SourceFiles/playerwidget.cpp
Normal file
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "style.h"
|
||||
#include "lang.h"
|
||||
|
||||
#include "boxes/addcontactbox.h"
|
||||
#include "application.h"
|
||||
#include "window.h"
|
||||
#include "playerwidget.h"
|
||||
#include "mainwidget.h"
|
||||
|
||||
#include "localstorage.h"
|
||||
|
||||
#include "audio.h"
|
||||
|
||||
PlayerWidget::PlayerWidget(QWidget *parent) : TWidget(parent),
|
||||
_prevAvailable(false), _nextAvailable(false), _fullAvailable(false),
|
||||
_over(OverNone), _down(OverNone), _downCoord(0), _downFrequency(AudioVoiceMsgFrequency), _downProgress(0.),
|
||||
_stateAnim(animFunc(this, &PlayerWidget::stateStep)),
|
||||
_index(-1), _history(0), _timeWidth(0), _repeat(false), _showPause(false), _position(0), _duration(0), _loaded(0),
|
||||
a_progress(0., 0.), a_loadProgress(0., 0.), _progressAnim(animFunc(this, &PlayerWidget::progressStep)) {
|
||||
resize(st::wndMinWidth, st::playerHeight);
|
||||
setMouseTracking(true);
|
||||
memset(_stateHovers, 0, sizeof(_stateHovers));
|
||||
}
|
||||
|
||||
void PlayerWidget::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
QRect r(e->rect()), checkr(myrtlrect(r));
|
||||
p.fillRect(r, st::playerBg->b);
|
||||
|
||||
if (!_playbackRect.contains(checkr)) {
|
||||
if (_fullAvailable && checkr.intersects(_prevRect)) {
|
||||
if (_prevAvailable) {
|
||||
float64 o = _stateHovers[OverPrev];
|
||||
p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
|
||||
} else {
|
||||
p.setOpacity(st::playerUnavailableOpacity);
|
||||
}
|
||||
p.drawSpriteCenterLeft(_prevRect, width(), st::playerPrev);
|
||||
}
|
||||
if (checkr.intersects(_playRect)) {
|
||||
float64 o = _stateHovers[OverPlay];
|
||||
p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
|
||||
p.drawSpriteCenterLeft(_playRect, width(), (_showPause || _down == OverPlayback) ? st::playerPause : st::playerPlay);
|
||||
}
|
||||
if (_fullAvailable && checkr.intersects(_nextRect)) {
|
||||
if (_nextAvailable) {
|
||||
float64 o = _stateHovers[OverNext];
|
||||
p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
|
||||
} else {
|
||||
p.setOpacity(st::playerUnavailableOpacity);
|
||||
}
|
||||
p.drawSpriteCenterLeft(_nextRect, width(), st::playerNext);
|
||||
}
|
||||
if (checkr.intersects(_closeRect)) {
|
||||
float64 o = _stateHovers[OverClose];
|
||||
p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
|
||||
p.drawSpriteCenterLeft(_closeRect, width(), st::playerClose);
|
||||
}
|
||||
if (checkr.intersects(_volumeRect)) {
|
||||
float64 o = _stateHovers[OverVolume];
|
||||
p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
|
||||
int32 top = _volumeRect.y() + (_volumeRect.height() - st::playerVolume.pxHeight()) / 2;
|
||||
int32 left = _volumeRect.x() + (_volumeRect.width() - st::playerVolume.pxWidth()) / 2;
|
||||
int32 mid = left + qRound(st::playerVolume.pxWidth() * cSongVolume());
|
||||
int32 right = left + st::playerVolume.pxWidth();
|
||||
if (rtl()) {
|
||||
left = width() - left;
|
||||
mid = width() - mid;
|
||||
right = width() - right;
|
||||
if (mid < left) {
|
||||
p.drawPixmap(QRect(mid, top, left - mid, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x() + (mid - right) * cIntRetinaFactor(), st::playerVolume.y(), (left - mid) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
|
||||
}
|
||||
if (right < mid) {
|
||||
p.setOpacity(st::playerUnavailableOpacity);
|
||||
p.drawPixmap(QRect(right, top, mid - right, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x(), st::playerVolume.y(), (mid - right) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
|
||||
}
|
||||
} else {
|
||||
if (mid > left) {
|
||||
p.drawPixmap(QRect(left, top, mid - left, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x(), st::playerVolume.y(), (mid - left) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
|
||||
}
|
||||
if (right > mid) {
|
||||
p.setOpacity(st::playerUnavailableOpacity);
|
||||
p.drawPixmap(QRect(mid, top, right - mid, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x() + (mid - left) * cIntRetinaFactor(), st::playerVolume.y(), (right - mid) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_fullAvailable && checkr.intersects(_fullRect)) {
|
||||
float64 o = _stateHovers[OverFull];
|
||||
p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
|
||||
p.drawSpriteCenterLeft(_fullRect, width(), st::playerFull);
|
||||
}
|
||||
if (checkr.intersects(_repeatRect)) {
|
||||
float64 o = _stateHovers[OverRepeat];
|
||||
p.setOpacity(_repeat ? 1. : (o * st::playerInactiveOpacity + (1. - o) * st::playerUnavailableOpacity));
|
||||
p.drawSpriteCenterLeft(_repeatRect, width(), st::playerRepeat);
|
||||
}
|
||||
p.setOpacity(1.);
|
||||
|
||||
p.setPen(st::playerTimeFg->p);
|
||||
p.setFont(st::linkFont->f);
|
||||
p.drawTextLeft(_infoRect.x() + _infoRect.width() - _timeWidth, _infoRect.y() + (_infoRect.height() - st::linkFont->height) / 2, width(), _time, _timeWidth);
|
||||
|
||||
textstyleSet(&st::playerNameStyle);
|
||||
p.setPen(st::playerFg->p);
|
||||
_name.drawElided(p, _infoRect.x() + (rtl() ? (_timeWidth + st::playerSkip) : 0), _infoRect.y() + (_infoRect.height() - st::linkFont->height) / 2, _infoRect.width() - _timeWidth - st::playerSkip);
|
||||
textstyleRestore();
|
||||
}
|
||||
|
||||
if (_duration) {
|
||||
float64 prg = (_down == OverPlayback) ? _downProgress : a_progress.current();
|
||||
int32 from = _playbackRect.x(), mid = qRound(_playbackRect.x() + prg * _playbackRect.width()), end = _playbackRect.x() + _playbackRect.width();
|
||||
if (mid > from) {
|
||||
p.fillRect(rtl() ? (width() - mid) : from, height() - st::playerLineHeight, mid - from, _playbackRect.height(), st::playerLineActive->b);
|
||||
}
|
||||
if (end > mid) {
|
||||
p.fillRect(rtl() ? (width() - end) : mid, height() - st::playerLineHeight, end - mid, st::playerLineHeight, st::playerLineInactive->b);
|
||||
}
|
||||
if (_stateHovers[OverPlayback] > 0) {
|
||||
p.setOpacity(_stateHovers[OverPlayback]);
|
||||
|
||||
int32 x = mid - (st::playerMoverSize.width() / 2);
|
||||
p.fillRect(rtl() ? (width() - x - st::playerMoverSize.width()) : x, height() - st::playerMoverSize.height(), st::playerMoverSize.width(), st::playerMoverSize.height(), st::playerLineActive->b);
|
||||
}
|
||||
} else if (a_loadProgress.current() > 0) {
|
||||
int32 from = _playbackRect.x(), mid = qRound(_playbackRect.x() + a_loadProgress.current() * _playbackRect.width());
|
||||
if (mid > from) {
|
||||
p.fillRect(rtl() ? (width() - mid) : from, height() - st::playerLineHeight, mid - from, _playbackRect.height(), st::playerLineInactive->b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::mousePressEvent(QMouseEvent *e) {
|
||||
QPoint pos(myrtlpoint(e->pos()));
|
||||
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
_down = OverNone;
|
||||
if (_song && _over == OverPlay) {
|
||||
playPausePressed();
|
||||
return;
|
||||
} else if (_over == OverPrev) {
|
||||
prevPressed();
|
||||
} else if (_over == OverNext) {
|
||||
nextPressed();
|
||||
} else if (_over == OverClose) {
|
||||
_down = OverClose;
|
||||
} else if (_over == OverVolume) {
|
||||
_down = OverVolume;
|
||||
_downCoord = pos.x() - _volumeRect.x();
|
||||
cSetSongVolume(snap((_downCoord - ((_volumeRect.width() - st::playerVolume.pxWidth()) / 2)) / float64(st::playerVolume.pxWidth()), 0., 1.));
|
||||
emit audioPlayer()->songVolumeChanged();
|
||||
rtlupdate(_volumeRect);
|
||||
} else if (_over == OverPlayback) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
int64 playingPosition = 0, playingDuration = 0;
|
||||
int32 playingFrequency = 0;
|
||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||
if (playing == _song && playingDuration) {
|
||||
if (playingState == AudioPlayerPlaying || playingState == AudioPlayerStarting || playingState == AudioPlayerResuming) {
|
||||
audioPlayer()->pauseresume(OverviewDocuments);
|
||||
}
|
||||
_down = OverPlayback;
|
||||
_downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.);
|
||||
_downDuration = playingDuration;
|
||||
_downFrequency = (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
|
||||
|
||||
rtlupdate(_playbackRect);
|
||||
updateDownTime();
|
||||
}
|
||||
} else if (_over == OverFull && _song) {
|
||||
if (HistoryItem *item = App::histItemById(_song.msgId)) {
|
||||
App::main()->showMediaOverview(item->history()->peer, OverviewAudioDocuments);
|
||||
}
|
||||
} else if (_over == OverRepeat) {
|
||||
_repeat = !_repeat;
|
||||
updateOverRect(OverRepeat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::updateDownTime() {
|
||||
QString time = formatDurationText(qRound(_downDuration * _downProgress) / _downFrequency);
|
||||
if (time != _time) {
|
||||
_time = time;
|
||||
_timeWidth = st::linkFont->m.width(_time);
|
||||
rtlupdate(_infoRect);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::updateOverState(OverState newState) {
|
||||
bool result = true;
|
||||
if (_over != newState) {
|
||||
updateOverRect(_over);
|
||||
updateOverRect(newState);
|
||||
if (_over != OverNone) {
|
||||
_stateAnimations.remove(_over);
|
||||
_stateAnimations[-_over] = getms() - ((1. - _stateHovers[_over]) * st::playerDuration);
|
||||
if (!_stateAnim.animating()) _stateAnim.start();
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
_over = newState;
|
||||
if (newState != OverNone) {
|
||||
_stateAnimations.remove(-_over);
|
||||
_stateAnimations[_over] = getms() - (_stateHovers[_over] * st::playerDuration);
|
||||
if (!_stateAnim.animating()) _stateAnim.start();
|
||||
setCursor(style::cur_pointer);
|
||||
} else {
|
||||
setCursor(style::cur_default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::updateOverRect(OverState state) {
|
||||
switch (state) {
|
||||
case OverPrev: rtlupdate(_prevRect); break;
|
||||
case OverPlay: rtlupdate(_playRect); break;
|
||||
case OverNext: rtlupdate(_nextRect); break;
|
||||
case OverClose: rtlupdate(_closeRect); break;
|
||||
case OverVolume: rtlupdate(_volumeRect); break;
|
||||
case OverFull: rtlupdate(_fullRect); break;
|
||||
case OverRepeat: rtlupdate(_repeatRect); break;
|
||||
case OverPlayback: rtlupdate(_playbackRect); break;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::updateControls() {
|
||||
_fullAvailable = (_index >= 0);
|
||||
_prevAvailable = _fullAvailable && (_index > 0);
|
||||
_nextAvailable = _fullAvailable && (_index < _history->_overview[OverviewAudioDocuments].size() - 1);
|
||||
resizeEvent(0);
|
||||
update();
|
||||
|
||||
if (_index >= 0 && _index < MediaOverviewStartPerPage) {
|
||||
if (_history->_overviewCount[OverviewAudioDocuments] < 0 || _history->_overviewCount[OverviewAudioDocuments] > 0) {
|
||||
if (App::main()) App::main()->loadMediaBack(_history->peer, OverviewAudioDocuments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::findCurrent() {
|
||||
_index = -1;
|
||||
if (!_history) return;
|
||||
|
||||
const History::MediaOverview *o = &_history->_overview[OverviewAudioDocuments];
|
||||
for (int i = 0, l = o->size(); i < l; ++i) {
|
||||
if (o->at(i) == _song.msgId) {
|
||||
_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_index < 0) return;
|
||||
|
||||
if (_index < o->size() - 1) {
|
||||
if (HistoryItem *next = App::histItemById(o->at(_index + 1))) {
|
||||
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
|
||||
if (document->document()->already(true).isEmpty() && document->document()->data.isEmpty()) {
|
||||
if (!document->document()->loader) {
|
||||
DocumentOpenLink::doOpen(document->document());
|
||||
document->document()->openOnSave = document->document()->openOnSaveMsgId = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::startPlay(MsgId msgId) {
|
||||
if (HistoryItem *item = App::histItemById(msgId)) {
|
||||
if (HistoryDocument *doc = static_cast<HistoryDocument*>(item->getMedia())) {
|
||||
audioPlayer()->play(SongMsgId(doc->document(), item->id));
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::clearSelection() {
|
||||
for (StateAnimations::const_iterator i = _stateAnimations.cbegin(); i != _stateAnimations.cend(); ++i) {
|
||||
_stateHovers[qAbs(i.key())] = 0;
|
||||
}
|
||||
_stateAnimations.clear();
|
||||
}
|
||||
|
||||
void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
if (_history && _history->peer == peer && type == OverviewAudioDocuments) {
|
||||
_index = -1;
|
||||
for (int i = 0, l = _history->_overview[OverviewAudioDocuments].size(); i < l; ++i) {
|
||||
if (_history->_overview[OverviewAudioDocuments].at(i) == _song.msgId) {
|
||||
_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateControls();
|
||||
}
|
||||
}
|
||||
|
||||
bool PlayerWidget::seekingSong(const SongMsgId &song) const {
|
||||
return (_down == OverPlayback) && (song == _song);
|
||||
}
|
||||
|
||||
bool PlayerWidget::stateStep(float64 msc) {
|
||||
bool result = false;
|
||||
uint64 ms = getms();
|
||||
for (StateAnimations::iterator i = _stateAnimations.begin(); i != _stateAnimations.cend();) {
|
||||
int32 over = qAbs(i.key());
|
||||
updateOverRect(OverState(over));
|
||||
|
||||
float64 dt = float64(ms - i.value()) / st::playerDuration;
|
||||
if (dt >= 1) {
|
||||
_stateHovers[over] = (i.key() > 0) ? 1 : 0;
|
||||
i = _stateAnimations.erase(i);
|
||||
} else {
|
||||
_stateHovers[over] = (i.key() > 0) ? dt : (1 - dt);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return !_stateAnimations.isEmpty();
|
||||
}
|
||||
|
||||
void PlayerWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||
_lastMousePos = e->globalPos();
|
||||
updateSelected();
|
||||
}
|
||||
|
||||
void PlayerWidget::leaveEvent(QEvent *e) {
|
||||
_lastMousePos = QCursor::pos();
|
||||
updateSelected();
|
||||
}
|
||||
|
||||
void PlayerWidget::updateSelected() {
|
||||
QPoint pos(myrtlpoint(mapFromGlobal(_lastMousePos)));
|
||||
|
||||
if (_down == OverVolume) {
|
||||
int32 delta = (pos.x() - _volumeRect.x()) - _downCoord;
|
||||
float64 startFrom = snap((_downCoord - ((_volumeRect.width() - st::playerVolume.pxWidth()) / 2)) / float64(st::playerVolume.pxWidth()), 0., 1.);
|
||||
float64 add = delta / float64(4 * st::playerVolume.pxWidth()), result = snap(startFrom + add, 0., 1.);
|
||||
if (result != cSongVolume()) {
|
||||
cSetSongVolume(result);
|
||||
emit audioPlayer()->songVolumeChanged();
|
||||
rtlupdate(_volumeRect);
|
||||
}
|
||||
} else if (_down == OverPlayback) {
|
||||
_downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.);
|
||||
rtlupdate(_playbackRect);
|
||||
updateDownTime();
|
||||
} else if (_down == OverNone) {
|
||||
bool inInfo = ((pos.x() >= _infoRect.x()) && (pos.x() < _fullRect.x() + _fullRect.width()) && (pos.y() >= _playRect.y()) && (pos.y() <= _playRect.y() + _playRect.height()));
|
||||
if (_prevAvailable && _prevRect.contains(pos)) {
|
||||
updateOverState(OverPrev);
|
||||
} else if (_nextAvailable && _nextRect.contains(pos)) {
|
||||
updateOverState(OverNext);
|
||||
} else if (_playRect.contains(pos)) {
|
||||
updateOverState(OverPlay);
|
||||
} else if (_closeRect.contains(pos)) {
|
||||
updateOverState(OverClose);
|
||||
} else if (_volumeRect.contains(pos)) {
|
||||
updateOverState(OverVolume);
|
||||
} else if (_repeatRect.contains(pos)) {
|
||||
updateOverState(OverRepeat);
|
||||
} else if (_duration && _playbackRect.contains(pos)) {
|
||||
updateOverState(OverPlayback);
|
||||
} else if (_fullAvailable && inInfo) {
|
||||
updateOverState(OverFull);
|
||||
} else if (_over != OverNone) {
|
||||
updateOverState(OverNone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (_down == OverVolume) {
|
||||
mouseMoveEvent(e);
|
||||
Local::writeUserSettings();
|
||||
} else if (_down == OverPlayback) {
|
||||
mouseMoveEvent(e);
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
int64 playingPosition = 0, playingDuration = 0;
|
||||
int32 playingFrequency = 0;
|
||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||
if (playing == _song && playingDuration) {
|
||||
_downDuration = playingDuration;
|
||||
audioPlayer()->seek(qRound(_downProgress * _downDuration));
|
||||
|
||||
_showPause = true;
|
||||
|
||||
a_progress = anim::fvalue(_downProgress, _downProgress);
|
||||
_progressAnim.stop();
|
||||
}
|
||||
update();
|
||||
} else if (_down == OverClose && _over == OverClose) {
|
||||
stopPressed();
|
||||
}
|
||||
_down = OverNone;
|
||||
}
|
||||
|
||||
void PlayerWidget::playPressed() {
|
||||
if (!_song || isHidden()) return;
|
||||
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &playingState);
|
||||
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
||||
if (playingState == AudioPlayerPausing || playingState == AudioPlayerPaused || playingState == AudioPlayerPausedAtEnd) {
|
||||
audioPlayer()->pauseresume(OverviewDocuments);
|
||||
}
|
||||
} else {
|
||||
audioPlayer()->play(_song);
|
||||
if (App::main()) App::main()->documentPlayProgress(_song);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::pausePressed() {
|
||||
if (!_song || isHidden()) return;
|
||||
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &playingState);
|
||||
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
||||
if (playingState == AudioPlayerStarting || playingState == AudioPlayerResuming || playingState == AudioPlayerPlaying || playingState == AudioPlayerFinishing) {
|
||||
audioPlayer()->pauseresume(OverviewDocuments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::playPausePressed() {
|
||||
if (!_song || isHidden()) return;
|
||||
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &playingState);
|
||||
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
||||
audioPlayer()->pauseresume(OverviewDocuments);
|
||||
} else {
|
||||
audioPlayer()->play(_song);
|
||||
if (App::main()) App::main()->documentPlayProgress(_song);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::prevPressed() {
|
||||
if (isHidden()) return;
|
||||
|
||||
const History::MediaOverview *o = _history ? &_history->_overview[OverviewAudioDocuments] : 0;
|
||||
if (audioPlayer() && o && _index > 0 && _index <= o->size() && !o->isEmpty()) {
|
||||
startPlay(o->at(_index - 1));
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::nextPressed() {
|
||||
if (isHidden()) return;
|
||||
|
||||
const History::MediaOverview *o = _history ? &_history->_overview[OverviewAudioDocuments] : 0;
|
||||
if (audioPlayer() && o && _index >= 0 && _index < o->size() - 1) {
|
||||
startPlay(o->at(_index + 1));
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerWidget::stopPressed() {
|
||||
if (!_song || isHidden()) return;
|
||||
|
||||
audioPlayer()->stop(OverviewDocuments);
|
||||
if (App::main()) App::main()->hidePlayer();
|
||||
}
|
||||
|
||||
void PlayerWidget::resizeEvent(QResizeEvent *e) {
|
||||
int32 availh = (height() - st::playerLineHeight);
|
||||
int32 ch = st::playerPlay.pxHeight() + st::playerSkip, ct = (availh - ch) / 2;
|
||||
_playbackRect = QRect(cWideMode() ? st::dlgShadow : 0, height() - st::playerMoverSize.height(), width() - (cWideMode() ? st::dlgShadow : 0), st::playerMoverSize.height());
|
||||
_prevRect = _fullAvailable ? QRect(st::playerSkip / 2, ct, st::playerPrev.pxWidth() + st::playerSkip, ch) : QRect();
|
||||
_playRect = QRect(_fullAvailable ? (_prevRect.x() + _prevRect.width()) : (st::playerSkip / 2), ct, st::playerPlay.pxWidth() + st::playerSkip, ch);
|
||||
_nextRect = _fullAvailable ? QRect(_playRect.x() + _playRect.width(), ct, st::playerNext.pxWidth() + st::playerSkip, ch) : QRect();
|
||||
|
||||
_closeRect = QRect(width() - st::playerSkip / 2 - st::playerClose.pxWidth() - st::playerSkip, ct, st::playerClose.pxWidth() + st::playerSkip, ch);
|
||||
_volumeRect = QRect(_closeRect.x() - st::playerVolume.pxWidth() - st::playerSkip, ct, st::playerVolume.pxWidth() + st::playerSkip, ch);
|
||||
_repeatRect = QRect(_volumeRect.x() - st::playerRepeat.pxWidth() - st::playerSkip, ct, st::playerRepeat.pxWidth() + st::playerSkip, ch);
|
||||
_fullRect = _fullAvailable ? QRect(_repeatRect.x() - st::playerFull.pxWidth() - st::playerSkip, ct, st::playerFull.pxWidth() + st::playerSkip, ch) : QRect();
|
||||
|
||||
int32 infoLeft = (_fullAvailable ? (_nextRect.x() + _nextRect.width()) : (_playRect.x() + _playRect.width()));
|
||||
_infoRect = QRect(infoLeft + st::playerSkip / 2, 0, (_fullAvailable ? _fullRect.x() : _repeatRect.x()) - infoLeft - st::playerSkip, availh);
|
||||
update();
|
||||
}
|
||||
|
||||
bool PlayerWidget::progressStep(float64 ms) {
|
||||
float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
|
||||
bool res = true;
|
||||
if (_duration && dt >= 1) {
|
||||
a_progress.finish();
|
||||
a_loadProgress.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_progress.update(qMin(dt, 1.), anim::linear);
|
||||
a_loadProgress.update(1. - (st::radialDuration / (st::radialDuration + ms)), anim::linear);
|
||||
}
|
||||
rtlupdate(_playbackRect);
|
||||
return res;
|
||||
}
|
||||
|
||||
void PlayerWidget::updateState() {
|
||||
updateState(SongMsgId(), AudioPlayerStopped, 0, 0, 0);
|
||||
}
|
||||
|
||||
void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency) {
|
||||
if (!playing) {
|
||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||
}
|
||||
|
||||
bool songChanged = false;
|
||||
if (playing && _song != playing) {
|
||||
songChanged = true;
|
||||
_song = playing;
|
||||
if (HistoryItem *item = App::histItemById(_song.msgId)) {
|
||||
_history = item->history();
|
||||
findCurrent();
|
||||
} else {
|
||||
_history = 0;
|
||||
_index = -1;
|
||||
}
|
||||
SongData *song = _song.song->song();
|
||||
if (song->performer.isEmpty()) {
|
||||
_name.setText(st::linkFont, song->title.isEmpty() ? (_song.song->name.isEmpty() ? qsl("Unknown Track") : _song.song->name) : song->title, _textNameOptions);
|
||||
} else {
|
||||
TextCustomTagsMap custom;
|
||||
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
|
||||
_name.setRichText(st::linkFont, QString::fromUtf8("[c]%1[/c] \xe2\x80\x93 %2").arg(textRichPrepare(song->performer)).arg(song->title.isEmpty() ? qsl("Unknown Track") : textRichPrepare(song->title)), _textNameOptions, custom);
|
||||
}
|
||||
updateControls();
|
||||
}
|
||||
|
||||
qint64 position = 0, duration = 0, display = 0;
|
||||
if (playing == _song) {
|
||||
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||
display = position = playingPosition;
|
||||
duration = playingDuration;
|
||||
} else {
|
||||
display = playingDuration;
|
||||
}
|
||||
display = display / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
|
||||
} else if (_song) {
|
||||
display = _song.song->song()->duration;
|
||||
}
|
||||
bool showPause = false, stopped = ((playingState & AudioPlayerStoppedMask) || playingState == AudioPlayerFinishing);
|
||||
bool wasPlaying = !!_duration;
|
||||
if (!stopped) {
|
||||
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
|
||||
}
|
||||
QString time;
|
||||
float64 progress = 0.;
|
||||
int32 loaded;
|
||||
float64 loadProgress = 1.;
|
||||
if (duration || !_song.song->loader) {
|
||||
time = (_down == OverPlayback) ? _time : formatDurationText(display);
|
||||
progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.;
|
||||
loaded = duration ? _song.song->size : 0;
|
||||
} else {
|
||||
loaded = _song.song->loader ? _song.song->loader->currentOffset() : 0;
|
||||
time = formatDownloadText(loaded, _song.song->size);
|
||||
loadProgress = snap(float64(loaded) / qMax(_song.song->size, 1), 0., 1.);
|
||||
}
|
||||
if (time != _time || showPause != _showPause) {
|
||||
if (_time != time) {
|
||||
_time = time;
|
||||
_timeWidth = st::linkFont->m.width(_time);
|
||||
}
|
||||
_showPause = showPause;
|
||||
if (duration != _duration || position != _position || loaded != _loaded) {
|
||||
if (!songChanged && ((!stopped && duration && _duration) || (!duration && _loaded != loaded))) {
|
||||
a_progress.start(progress);
|
||||
a_loadProgress.start(loadProgress);
|
||||
_progressAnim.start();
|
||||
} else {
|
||||
a_progress = anim::fvalue(progress, progress);
|
||||
a_loadProgress = anim::fvalue(loadProgress, loadProgress);
|
||||
_progressAnim.stop();
|
||||
}
|
||||
_position = position;
|
||||
_duration = duration;
|
||||
_loaded = loaded;
|
||||
}
|
||||
update();
|
||||
} else if (duration != _duration || position != _position || loaded != _loaded) {
|
||||
if (!songChanged && ((!stopped && duration && _duration) || (!duration && _loaded != loaded))) {
|
||||
a_progress.start(progress);
|
||||
a_loadProgress.start(loadProgress);
|
||||
_progressAnim.start();
|
||||
} else {
|
||||
a_progress = anim::fvalue(progress, progress);
|
||||
a_loadProgress = anim::fvalue(loadProgress, loadProgress);
|
||||
_progressAnim.stop();
|
||||
}
|
||||
_position = position;
|
||||
_duration = duration;
|
||||
_loaded = loaded;
|
||||
}
|
||||
|
||||
if (wasPlaying && playingState == AudioPlayerStoppedAtEnd) {
|
||||
if (_repeat) {
|
||||
startPlay(_song.msgId);
|
||||
} else {
|
||||
nextPressed();
|
||||
}
|
||||
}
|
||||
|
||||
if (songChanged) {
|
||||
emit playerSongChanged(_song.msgId);
|
||||
}
|
||||
}
|
||||
113
Telegram/SourceFiles/playerwidget.h
Normal file
113
Telegram/SourceFiles/playerwidget.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "audio.h"
|
||||
|
||||
class PlayerWidget : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
PlayerWidget(QWidget *parent);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
void playPressed();
|
||||
void pausePressed();
|
||||
void playPausePressed();
|
||||
void prevPressed();
|
||||
void nextPressed();
|
||||
void stopPressed();
|
||||
|
||||
bool progressStep(float64 ms);
|
||||
bool stateStep(float64 ms);
|
||||
|
||||
void updateState(SongMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency);
|
||||
void updateState();
|
||||
void clearSelection();
|
||||
|
||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||
|
||||
bool seekingSong(const SongMsgId &song) const;
|
||||
|
||||
signals:
|
||||
|
||||
void playerSongChanged(MsgId msgId);
|
||||
|
||||
private:
|
||||
|
||||
enum OverState {
|
||||
OverNone = 0,
|
||||
OverPrev,
|
||||
OverPlay,
|
||||
OverNext,
|
||||
OverClose,
|
||||
OverVolume,
|
||||
OverFull,
|
||||
OverRepeat,
|
||||
OverPlayback,
|
||||
|
||||
OverStateCount
|
||||
};
|
||||
void updateDownTime();
|
||||
void updateOverState(OverState newState);
|
||||
void updateOverRect(OverState state);
|
||||
|
||||
void updateControls();
|
||||
void findCurrent();
|
||||
|
||||
void startPlay(MsgId msgId);
|
||||
|
||||
QPoint _lastMousePos;
|
||||
void updateSelected();
|
||||
|
||||
bool _prevAvailable, _nextAvailable, _fullAvailable;
|
||||
OverState _over, _down;
|
||||
int32 _downCoord;
|
||||
int64 _downDuration;
|
||||
int32 _downFrequency;
|
||||
float64 _downProgress;
|
||||
|
||||
float64 _stateHovers[OverStateCount];
|
||||
typedef QMap<int32, uint64> StateAnimations;
|
||||
StateAnimations _stateAnimations;
|
||||
Animation _stateAnim;
|
||||
|
||||
SongMsgId _song;
|
||||
int32 _index;
|
||||
History *_history;
|
||||
QRect _playRect, _prevRect, _nextRect, _playbackRect;
|
||||
QRect _closeRect, _volumeRect, _fullRect, _repeatRect, _infoRect;
|
||||
int32 _timeWidth;
|
||||
bool _repeat;
|
||||
QString _time;
|
||||
Text _name;
|
||||
bool _showPause;
|
||||
int64 _position, _duration;
|
||||
int32 _loaded;
|
||||
|
||||
anim::fvalue a_progress, a_loadProgress;
|
||||
Animation _progressAnim;
|
||||
|
||||
};
|
||||
@@ -77,14 +77,21 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
|
||||
if (_peerUser) {
|
||||
_phoneText = _peerUser->phone.isEmpty() ? QString() : App::formatPhone(_peerUser->phone);
|
||||
App::api()->requestFullPeer(_peer);
|
||||
} else if (_peerChat->photoId) {
|
||||
PhotoData *ph = App::photo(_peerChat->photoId);
|
||||
if (ph->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(ph, _peer));
|
||||
PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0;
|
||||
if (userPhoto && userPhoto->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(userPhoto, _peer));
|
||||
}
|
||||
if ((_peerUser->botInfo && !_peerUser->botInfo->inited) || (_peerUser->photoId == UnknownPeerPhotoId) || (_peerUser->photoId && !userPhoto->date)) {
|
||||
App::api()->requestFullPeer(_peer);
|
||||
}
|
||||
} else {
|
||||
App::api()->requestFullPeer(_peer);
|
||||
PhotoData *chatPhoto = (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) ? App::photo(_peerChat->photoId) : 0;
|
||||
if (chatPhoto && chatPhoto->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer));
|
||||
}
|
||||
if (_peerChat->photoId == UnknownPeerPhotoId) {
|
||||
App::api()->requestFullPeer(_peer);
|
||||
}
|
||||
}
|
||||
|
||||
// profile
|
||||
@@ -300,7 +307,6 @@ void ProfileInner::onMediaAudios() {
|
||||
}
|
||||
|
||||
void ProfileInner::onInvitationLink() {
|
||||
DEBUG_LOG(("Setting text to clipboard from invite url: %1").arg(_peerChat->invitationUrl));
|
||||
QApplication::clipboard()->setText(_peerChat->invitationUrl);
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_group_invite_copied), true));
|
||||
}
|
||||
@@ -326,7 +332,7 @@ void ProfileInner::chatInviteDone(const MTPExportedChatInvite &result) {
|
||||
void ProfileInner::onFullPeerUpdated(PeerData *peer) {
|
||||
if (peer != _peer) return;
|
||||
if (_peerUser) {
|
||||
PhotoData *userPhoto = _peerUser->photoId ? App::photo(_peerUser->photoId) : 0;
|
||||
PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0;
|
||||
if (userPhoto && userPhoto->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(userPhoto, _peer));
|
||||
} else {
|
||||
@@ -377,9 +383,9 @@ void ProfileInner::peerUpdated(PeerData *data) {
|
||||
PhotoData *photo = 0;
|
||||
if (_peerUser) {
|
||||
_phoneText = _peerUser->phone.isEmpty() ? QString() : App::formatPhone(_peerUser->phone);
|
||||
if (_peerUser->photoId) photo = App::photo(_peerUser->photoId);
|
||||
if (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) photo = App::photo(_peerUser->photoId);
|
||||
} else {
|
||||
if (_peerChat->photoId) photo = App::photo(_peerChat->photoId);
|
||||
if (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) photo = App::photo(_peerChat->photoId);
|
||||
}
|
||||
_photoLink = (photo && photo->date) ? TextLinkPtr(new PhotoLink(photo, _peer)) : TextLinkPtr();
|
||||
if (_peer->name != _nameCache) {
|
||||
@@ -512,7 +518,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
p.setPen(st::black->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username);
|
||||
}
|
||||
p.setPen((_peerUser && App::onlineColorUse(_peerUser->onlineTill, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
|
||||
p.setPen((_peerUser && App::onlineColorUse(_peerUser, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop + st::linkFont->ascent, _onlineText);
|
||||
if (_chatAdmin && !_peerChat->invitationUrl.isEmpty()) {
|
||||
p.setPen(st::black->p);
|
||||
@@ -573,6 +579,8 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
p.setPen(st::black->p);
|
||||
int oneState = 0; // < 0 - loading, 0 - no media, > 0 - link shown
|
||||
for (int i = 0; i < OverviewCount; ++i) {
|
||||
if (i == OverviewAudioDocuments) continue;
|
||||
|
||||
int32 count = (_hist->_overviewCount[i] > 0) ? _hist->_overviewCount[i] : (_hist->_overviewCount[i] == 0 ? _hist->_overview[i].size() : -1);
|
||||
if (count < 0) {
|
||||
if (!oneState) oneState = count;
|
||||
@@ -643,7 +651,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
p.setFont(st::linkFont->f);
|
||||
data->name.drawElided(p, _left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListNameTop, _width - _kickWidth - st::profileListPadding.width() - st::profileListPhotoSize - st::profileListPadding.width());
|
||||
p.setFont(st::profileSubFont->f);
|
||||
p.setPen((App::onlineColorUse(user->onlineTill, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
|
||||
p.setPen((App::onlineColorUse(user, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
|
||||
p.drawText(_left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListPadding.height() + st::profileListPhotoSize - st::profileListStatusBottom, data->online);
|
||||
|
||||
if (data->cankick) {
|
||||
@@ -853,6 +861,8 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
_mediaShowAll.move(_left + _width - _mediaShowAll.width(), top);
|
||||
int wasCount = 0; // < 0 - loading, 0 - no media, > 0 - link shown
|
||||
for (int i = 0; i < OverviewCount; ++i) {
|
||||
if (i == OverviewAudioDocuments) continue;
|
||||
|
||||
if (_allMediaTypes) {
|
||||
int32 count = (_hist->_overviewCount[i] > 0) ? _hist->_overviewCount[i] : (_hist->_overviewCount[i] == 0 ? _hist->_overview[i].size() : -1);
|
||||
if (count > 0) {
|
||||
@@ -906,12 +916,10 @@ void ProfileInner::onMenuDestroy(QObject *obj) {
|
||||
}
|
||||
|
||||
void ProfileInner::onCopyPhone() {
|
||||
DEBUG_LOG(("Setting text to clipboard from user phone: %1").arg(_phoneText));
|
||||
QApplication::clipboard()->setText(_phoneText);
|
||||
}
|
||||
|
||||
void ProfileInner::onCopyUsername() {
|
||||
DEBUG_LOG(("Setting text to clipboard from username: @%1").arg(_peerUser->username));
|
||||
QApplication::clipboard()->setText('@' + _peerUser->username);
|
||||
}
|
||||
|
||||
@@ -953,7 +961,7 @@ void ProfileInner::updateNotifySettings() {
|
||||
_enableNotifications.setChecked(_peer->notify == EmptyNotifySettings || _peer->notify == UnknownNotifySettings || _peer->notify->mute < unixtime());
|
||||
}
|
||||
|
||||
void ProfileInner::mediaOverviewUpdated(PeerData *peer) {
|
||||
void ProfileInner::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
if (peer == _peer) {
|
||||
resizeEvent(0);
|
||||
showAll();
|
||||
@@ -1025,6 +1033,8 @@ void ProfileInner::showAll() {
|
||||
// shared media
|
||||
bool first = false, wasCount = false, manyCounts = false;
|
||||
for (int i = 0; i < OverviewCount; ++i) {
|
||||
if (i == OverviewAudioDocuments) continue;
|
||||
|
||||
int32 count = (_hist->_overviewCount[i] > 0) ? _hist->_overviewCount[i] : (_hist->_overviewCount[i] == 0 ? _hist->_overview[i].size() : -1);
|
||||
if (count > 0) {
|
||||
if (wasCount) {
|
||||
@@ -1079,9 +1089,9 @@ void ProfileInner::updateInvitationLink() {
|
||||
} else {
|
||||
_createInvitationLink.setText(lang(lng_group_invite_create_new));
|
||||
_invitationText = _peerChat->invitationUrl;
|
||||
if (_invitationText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive)) {
|
||||
if (_invitationText.startsWith(qstr("http://"), Qt::CaseInsensitive)) {
|
||||
_invitationText = _invitationText.mid(7);
|
||||
} else if (_invitationText.startsWith(QLatin1String("https://"), Qt::CaseInsensitive)) {
|
||||
} else if (_invitationText.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
|
||||
_invitationText = _invitationText.mid(8);
|
||||
}
|
||||
}
|
||||
@@ -1132,8 +1142,13 @@ void ProfileWidget::onScroll() {
|
||||
}
|
||||
|
||||
void ProfileWidget::resizeEvent(QResizeEvent *e) {
|
||||
int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0;
|
||||
int32 newScrollY = _scroll.scrollTop() + addToY;
|
||||
_scroll.resize(size());
|
||||
_inner.resize(width(), _inner.height());
|
||||
if (addToY) {
|
||||
_scroll.scrollToY(newScrollY);
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileWidget::mousePressEvent(QMouseEvent *e) {
|
||||
@@ -1172,6 +1187,13 @@ void ProfileWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth)
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileWidget::topBarShadowParams(int32 &x, float64 &o) {
|
||||
if (animating() && a_coord.current() >= 0) {
|
||||
x = a_coord.current();
|
||||
o = a_alpha.current();
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileWidget::topBarClick() {
|
||||
App::main()->showBackFromStack();
|
||||
}
|
||||
@@ -1249,8 +1271,8 @@ void ProfileWidget::updateNotifySettings() {
|
||||
_inner.updateNotifySettings();
|
||||
}
|
||||
|
||||
void ProfileWidget::mediaOverviewUpdated(PeerData *peer) {
|
||||
_inner.mediaOverviewUpdated(peer);
|
||||
void ProfileWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
_inner.mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
|
||||
void ProfileWidget::clear() {
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
void loadProfilePhotos(int32 yFrom);
|
||||
|
||||
void updateNotifySettings();
|
||||
void mediaOverviewUpdated(PeerData *peer);
|
||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||
|
||||
~ProfileInner();
|
||||
|
||||
@@ -187,6 +187,7 @@ public:
|
||||
void dropEvent(QDropEvent *e);
|
||||
|
||||
void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
|
||||
void topBarShadowParams(int32 &x, float64 &o);
|
||||
void topBarClick();
|
||||
|
||||
PeerData *peer() const;
|
||||
@@ -200,7 +201,7 @@ public:
|
||||
void updateOnlineDisplayTimer();
|
||||
|
||||
void updateNotifySettings();
|
||||
void mediaOverviewUpdated(PeerData *peer);
|
||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||
|
||||
void clear();
|
||||
~ProfileWidget();
|
||||
|
||||
@@ -352,7 +352,7 @@ namespace {
|
||||
public:
|
||||
_PsInitializer() {
|
||||
QString cdesktop = QString(getenv("XDG_CURRENT_DESKTOP")).toLower();
|
||||
noQtTrayIcon = (cdesktop == QLatin1String("unity")) || (cdesktop == QLatin1String("pantheon")) || (cdesktop == QLatin1String("gnome"));
|
||||
noQtTrayIcon = (cdesktop == qstr("unity")) || (cdesktop == qstr("pantheon")) || (cdesktop == qstr("gnome"));
|
||||
|
||||
if (noQtTrayIcon) cSetSupportTray(false);
|
||||
std::cout << "libs init..\n";
|
||||
@@ -460,7 +460,7 @@ namespace {
|
||||
void setupUnity() {
|
||||
if (!useGtkBase || !noQtTrayIcon) return;
|
||||
|
||||
QLibrary lib_unity(QLatin1String("unity"), 9, 0);
|
||||
QLibrary lib_unity(qstr("unity"), 9, 0);
|
||||
if (!loadLibrary(lib_unity, "unity", 9)) return;
|
||||
|
||||
if (!loadFunction(lib_unity, "unity_launcher_entry_get_for_desktop_id", ps_unity_launcher_entry_get_for_desktop_id)) return;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace {
|
||||
Window *wnd = Application::wnd();
|
||||
if (!wnd) return false;
|
||||
|
||||
return false;
|
||||
return wnd->psFilterNativeEvent(message);
|
||||
}
|
||||
};
|
||||
_PsEventFilter *_psEventFilter = 0;
|
||||
@@ -460,6 +460,10 @@ void PsMainWindow::psActivateNotify(NotifyWindow *w) {
|
||||
objc_activateWnd(w->winId());
|
||||
}
|
||||
|
||||
bool PsMainWindow::psFilterNativeEvent(void *event) {
|
||||
return _private.filterNativeEvent(event);
|
||||
}
|
||||
|
||||
namespace {
|
||||
QRect _monitorRect;
|
||||
uint64 _monitorLastGot = 0;
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
void darkModeChanged();
|
||||
void notifyClicked(unsigned long long peer, int msgid);
|
||||
void notifyReplied(unsigned long long peer, int msgid, const char *str);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class NotifyWindow;
|
||||
@@ -72,6 +72,8 @@ public:
|
||||
return posInited;
|
||||
}
|
||||
|
||||
bool psFilterNativeEvent(void *event);
|
||||
|
||||
void psActivateNotify(NotifyWindow *w);
|
||||
void psClearNotifies(PeerId peerId = 0);
|
||||
void psNotifyShown(NotifyWindow *w);
|
||||
|
||||
@@ -33,7 +33,9 @@ public:
|
||||
void clearNotifies(uint64 peer = 0);
|
||||
|
||||
void enableShadow(WId winId);
|
||||
|
||||
|
||||
bool filterNativeEvent(void *event);
|
||||
|
||||
virtual void activeSpaceChanged() {
|
||||
}
|
||||
virtual void darkModeChanged() {
|
||||
|
||||
@@ -19,6 +19,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include "pspecific_mac_p.h"
|
||||
|
||||
#include "window.h"
|
||||
#include "mainwidget.h"
|
||||
#include "application.h"
|
||||
|
||||
#include "lang.h"
|
||||
@@ -27,6 +28,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <CoreFoundation/CFURL.h>
|
||||
|
||||
#include <IOKit/hidsystem/ev_keymap.h>
|
||||
|
||||
@interface qVisualize : NSObject {
|
||||
}
|
||||
|
||||
@@ -304,6 +307,41 @@ void PsMacWindowPrivate::enableShadow(WId winId) {
|
||||
// [[(NSView*)winId window] setHasShadow:YES];
|
||||
}
|
||||
|
||||
bool PsMacWindowPrivate::filterNativeEvent(void *event) {
|
||||
NSEvent *e = static_cast<NSEvent*>(event);
|
||||
if (e && [e type] == NSSystemDefined && [e subtype] == 8) {
|
||||
int keyCode = (([e data1] & 0xFFFF0000) >> 16);
|
||||
int keyFlags = ([e data1] & 0x0000FFFF);
|
||||
int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA;
|
||||
int keyRepeat = (keyFlags & 0x1);
|
||||
|
||||
switch (keyCode) {
|
||||
case NX_KEYTYPE_PLAY:
|
||||
if (keyState == 0) { // Play pressed and released
|
||||
if (App::main()) App::main()->player()->playPausePressed();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case NX_KEYTYPE_FAST:
|
||||
if (keyState == 0) { // Next pressed and released
|
||||
if (App::main()) App::main()->player()->nextPressed();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case NX_KEYTYPE_REWIND:
|
||||
if (keyState == 0) { // Previous pressed and released
|
||||
if (App::main()) App::main()->player()->prevPressed();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PsMacWindowPrivate::clearNotifies(unsigned long long peer) {
|
||||
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
|
||||
if (peer) {
|
||||
|
||||
@@ -52,6 +52,11 @@ bool gSupportTray = true;
|
||||
DBIWorkMode gWorkMode = dbiwmWindowAndTray;
|
||||
DBIConnectionType gConnectionType = dbictAuto;
|
||||
ConnectionProxy gConnectionProxy;
|
||||
#ifdef Q_OS_WIN
|
||||
bool gTryIPv6 = false;
|
||||
#else
|
||||
bool gTryIPv6 = true;
|
||||
#endif
|
||||
bool gSeenTrayTooltip = false;
|
||||
bool gRestartingUpdate = false, gRestarting = false, gRestartingToSettings = false, gWriteProtected = false;
|
||||
int32 gLastUpdateCheck = 0;
|
||||
@@ -94,8 +99,6 @@ EmojiColorVariants gEmojiVariants;
|
||||
|
||||
QByteArray gStickersHash;
|
||||
|
||||
EmojiStickersMap gEmojiStickers;
|
||||
|
||||
RecentStickerPreload gRecentStickersPreload;
|
||||
RecentStickerPack gRecentStickers;
|
||||
StickerSets gStickerSets;
|
||||
@@ -153,6 +156,8 @@ int gNotifyDefaultDelay = 1500;
|
||||
|
||||
int gOtherOnline = 0;
|
||||
|
||||
float64 gSongVolume = 0.9;
|
||||
|
||||
void settingsParseArgs(int argc, char *argv[]) {
|
||||
#ifdef Q_OS_MAC
|
||||
gCustomNotifies = (QSysInfo::macVersion() < QSysInfo::MV_10_8);
|
||||
@@ -286,7 +291,7 @@ RecentStickerPack &cGetRecentStickers() {
|
||||
recent.reserve(p.size());
|
||||
for (RecentStickerPreload::const_iterator i = p.cbegin(), e = p.cend(); i != e; ++i) {
|
||||
DocumentData *doc = App::document(i->first);
|
||||
if (!doc || !doc->sticker) continue;
|
||||
if (!doc || !doc->sticker()) continue;
|
||||
|
||||
recent.push_back(qMakePair(doc, i->second));
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ DeclareSetting(TWindowPos, WindowPos);
|
||||
DeclareSetting(bool, SupportTray);
|
||||
DeclareSetting(DBIWorkMode, WorkMode);
|
||||
DeclareSetting(DBIConnectionType, ConnectionType);
|
||||
DeclareSetting(bool, TryIPv6);
|
||||
DeclareSetting(DBIDefaultAttach, DefaultAttach);
|
||||
DeclareSetting(ConnectionProxy, ConnectionProxy);
|
||||
DeclareSetting(bool, SeenTrayTooltip);
|
||||
@@ -188,9 +189,6 @@ struct DocumentData;
|
||||
typedef QVector<DocumentData*> StickerPack;
|
||||
DeclareSetting(QByteArray, StickersHash);
|
||||
|
||||
typedef QMap<DocumentData*, EmojiPtr> EmojiStickersMap;
|
||||
DeclareSetting(EmojiStickersMap, EmojiStickers);
|
||||
|
||||
typedef QList<QPair<DocumentData*, int16> > RecentStickerPackOld;
|
||||
typedef QVector<QPair<uint64, ushort> > RecentStickerPreload;
|
||||
typedef QVector<QPair<DocumentData*, ushort> > RecentStickerPack;
|
||||
@@ -201,12 +199,14 @@ RecentStickerPack &cGetRecentStickers();
|
||||
|
||||
DeclareSetting(uint64, LastStickersUpdate);
|
||||
|
||||
static const uint64 DefaultStickerSetId = 0, CustomStickerSetId = 0xFFFFFFFFFFFFFFFFLLU, RecentStickerSetId = 0xFFFFFFFFFFFFFFFELLU;
|
||||
static const uint64 DefaultStickerSetId = 0; // for backward compatibility
|
||||
static const uint64 CustomStickerSetId = 0xFFFFFFFFFFFFFFFFLLU, RecentStickerSetId = 0xFFFFFFFFFFFFFFFELLU;
|
||||
struct StickerSet {
|
||||
StickerSet(uint64 id, uint64 access, const QString &title, const QString &shortName) : id(id), access(access), title(title), shortName(shortName) {
|
||||
StickerSet(uint64 id, uint64 access, const QString &title, const QString &shortName, int32 count, int32 hash, int32 flags) : id(id), access(access), title(title), shortName(shortName), count(count), hash(hash), flags(flags) {
|
||||
}
|
||||
uint64 id, access;
|
||||
QString title, shortName;
|
||||
int32 count, hash, flags;
|
||||
StickerPack stickers;
|
||||
};
|
||||
typedef QMap<uint64, StickerSet> StickerSets;
|
||||
@@ -304,4 +304,6 @@ DeclareSetting(int, NotifyDefaultDelay);
|
||||
|
||||
DeclareSetting(int, OtherOnline);
|
||||
|
||||
DeclareSetting(float64, SongVolume);
|
||||
|
||||
void settingsParseArgs(int argc, char *argv[]);
|
||||
|
||||
@@ -182,7 +182,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
_passwordEdit(this, lang(lng_cloud_password_set)),
|
||||
_passwordTurnOff(this, lang(lng_passcode_turn_off)),
|
||||
_hasPasswordRecovery(false),
|
||||
_connectionType(this, lng_connection_auto(lt_type, QString())),
|
||||
_connectionType(this, lang(lng_connection_auto_connecting)),
|
||||
_connectionTypeText(lang(lng_connection_type) + ' '),
|
||||
_connectionTypeWidth(st::linkFont->m.width(_connectionTypeText)),
|
||||
_showSessions(this, lang(lng_settings_show_sessions)),
|
||||
@@ -190,7 +190,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
{
|
||||
if (self()) {
|
||||
_nameText.setText(st::setNameFont, _nameCache, _textNameOptions);
|
||||
PhotoData *selfPhoto = self()->photoId ? 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()));
|
||||
MTP::send(MTPusers_GetFullUser(self()->inputUser), rpcDone(&SettingsInner::gotFullSelf), RPCFailHandlerPtr(), 0, 10);
|
||||
onReloadPassword();
|
||||
@@ -312,7 +312,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
|
||||
void SettingsInner::peerUpdated(PeerData *data) {
|
||||
if (self() && data == self()) {
|
||||
if (self()->photoId) {
|
||||
if (self()->photoId && self()->photoId != UnknownPeerPhotoId) {
|
||||
PhotoData *selfPhoto = App::photo(self()->photoId);
|
||||
if (selfPhoto->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self()));
|
||||
@@ -731,14 +731,14 @@ void SettingsInner::keyPressEvent(QKeyEvent *e) {
|
||||
int32 size = _secretText.size(), from = 0;
|
||||
while (size > from) {
|
||||
QStringRef str(_secretText.midRef(from));
|
||||
if (str == QLatin1String("debugmode")) {
|
||||
if (str == qstr("debugmode")) {
|
||||
QString text = cDebug() ? qsl("Do you want to disable DEBUG logs?") : qsl("Do you want to enable DEBUG logs?\n\nAll network events will be logged.");
|
||||
ConfirmBox *box = new ConfirmBox(text);
|
||||
connect(box, SIGNAL(confirmed()), App::app(), SLOT(onSwitchDebugMode()));
|
||||
App::wnd()->showLayer(box);
|
||||
from = size;
|
||||
break;
|
||||
} else if (str == QLatin1String("testmode")) {
|
||||
} else if (str == qstr("testmode")) {
|
||||
QString text = cTestMode() ? qsl("Do you want to disable TEST mode?") : qsl("Do you want to enable TEST mode?\n\nYou will be switched to test cloud.");
|
||||
ConfirmBox *box = new ConfirmBox(text);
|
||||
connect(box, SIGNAL(confirmed()), App::app(), SLOT(onSwitchTestMode()));
|
||||
@@ -820,18 +820,19 @@ void SettingsInner::updateOnlineDisplay() {
|
||||
}
|
||||
|
||||
void SettingsInner::updateConnectionType() {
|
||||
QString connection;
|
||||
switch (cConnectionType()) {
|
||||
case dbictAuto: {
|
||||
QString transport = MTP::dctransport();
|
||||
if (transport.isEmpty()) {
|
||||
_connectionType.setText(lang(lng_connection_auto_connecting));
|
||||
} else {
|
||||
_connectionType.setText(lng_connection_auto(lt_type, transport));
|
||||
}
|
||||
connection = transport.isEmpty() ? lang(lng_connection_auto_connecting) : lng_connection_auto(lt_transport, transport);
|
||||
} break;
|
||||
case dbictHttpProxy:
|
||||
case dbictTcpProxy: {
|
||||
QString transport = MTP::dctransport();
|
||||
connection = transport.isEmpty() ? lang(lng_connection_proxy_connecting) : lng_connection_proxy(lt_transport, transport);
|
||||
} break;
|
||||
case dbictHttpProxy: _connectionType.setText(lang(lng_connection_http_proxy)); break;
|
||||
case dbictTcpProxy: _connectionType.setText(lang(lng_connection_tcp_proxy)); break;
|
||||
}
|
||||
_connectionType.setText(connection);
|
||||
}
|
||||
|
||||
void SettingsInner::passcodeChanged() {
|
||||
@@ -850,7 +851,7 @@ void SettingsInner::gotFullSelf(const MTPUserFull &selfFull) {
|
||||
if (!self()) return;
|
||||
App::feedPhoto(selfFull.c_userFull().vprofile_photo);
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, selfFull.c_userFull().vuser));
|
||||
PhotoData *selfPhoto = self()->photoId ? 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()));
|
||||
} else {
|
||||
|
||||
@@ -126,30 +126,38 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone,
|
||||
NameFirstChars oldChars = chars;
|
||||
fillNames();
|
||||
App::history(id)->updateNameText();
|
||||
nameUpdated();
|
||||
if (App::main()) {
|
||||
emit App::main()->peerNameChanged(this, oldNames, oldChars);
|
||||
}
|
||||
nameUpdated();
|
||||
}
|
||||
|
||||
void UserData::setPhoto(const MTPUserProfilePhoto &p) {
|
||||
PhotoId newPhotoId = photoId;
|
||||
ImagePtr newPhoto = photo;
|
||||
switch (p.type()) {
|
||||
case mtpc_userProfilePhoto: {
|
||||
const MTPDuserProfilePhoto d(p.c_userProfilePhoto());
|
||||
photoId = d.vphoto_id.v;
|
||||
photo = ImagePtr(160, 160, d.vphoto_small, userDefPhoto(colorIndex));
|
||||
// App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p));
|
||||
newPhotoId = d.vphoto_id.v;
|
||||
newPhoto = ImagePtr(160, 160, d.vphoto_small, userDefPhoto(colorIndex));
|
||||
//App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p));
|
||||
} break;
|
||||
default: {
|
||||
photoId = 0;
|
||||
newPhotoId = 0;
|
||||
if (id == ServiceUserId) {
|
||||
photo = ImagePtr(QPixmap::fromImage(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation), Qt::ColorOnly), "PNG");
|
||||
if (photo->isNull()) {
|
||||
newPhoto = ImagePtr(QPixmap::fromImage(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation), Qt::ColorOnly), "PNG");
|
||||
}
|
||||
} else {
|
||||
photo = userDefPhoto(colorIndex);
|
||||
newPhoto = userDefPhoto(colorIndex);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
emit App::main()->peerPhotoChanged(this);
|
||||
if (newPhotoId != photoId || newPhoto.v() != photo.v()) {
|
||||
photoId = newPhotoId;
|
||||
photo = newPhoto;
|
||||
emit App::main()->peerPhotoChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerData::fillNames() {
|
||||
@@ -198,7 +206,6 @@ void UserData::setName(const QString &first, const QString &last, const QString
|
||||
|
||||
void UserData::setPhone(const QString &newPhone) {
|
||||
phone = newPhone;
|
||||
++nameVersion;
|
||||
}
|
||||
|
||||
void UserData::setBotInfoVersion(int32 version) {
|
||||
@@ -209,7 +216,10 @@ void UserData::setBotInfoVersion(int32 version) {
|
||||
botInfo = new BotInfo();
|
||||
botInfo->version = version;
|
||||
} else if (botInfo->version < version) {
|
||||
botInfo->commands.clear();
|
||||
if (!botInfo->commands.isEmpty()) {
|
||||
botInfo->commands.clear();
|
||||
if (App::main()) App::main()->botCommandsChanged(this);
|
||||
}
|
||||
botInfo->description.clear();
|
||||
botInfo->shareText.clear();
|
||||
botInfo->version = version;
|
||||
@@ -219,6 +229,9 @@ void UserData::setBotInfoVersion(int32 version) {
|
||||
void UserData::setBotInfo(const MTPBotInfo &info) {
|
||||
switch (info.type()) {
|
||||
case mtpc_botInfoEmpty:
|
||||
if (botInfo && !botInfo->commands.isEmpty()) {
|
||||
if (App::main()) App::main()->botCommandsChanged(this);
|
||||
}
|
||||
delete botInfo;
|
||||
botInfo = 0;
|
||||
break;
|
||||
@@ -240,15 +253,37 @@ void UserData::setBotInfo(const MTPBotInfo &info) {
|
||||
botInfo->shareText = qs(d.vshare_text);
|
||||
|
||||
const QVector<MTPBotCommand> &v(d.vcommands.c_vector().v);
|
||||
botInfo->commands.clear();
|
||||
botInfo->commands.reserve(v.size());
|
||||
bool changedCommands = false;
|
||||
int32 j = 0;
|
||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||
if (v.at(i).type() == mtpc_botCommand) {
|
||||
botInfo->commands.push_back(BotCommand(qs(v.at(i).c_botCommand().vcommand), qs(v.at(i).c_botCommand().vdescription)));
|
||||
if (v.at(i).type() != mtpc_botCommand) continue;
|
||||
|
||||
QString cmd = qs(v.at(i).c_botCommand().vcommand), desc = qs(v.at(i).c_botCommand().vdescription);
|
||||
if (botInfo->commands.size() <= j) {
|
||||
botInfo->commands.push_back(BotCommand(cmd, desc));
|
||||
changedCommands = true;
|
||||
} else {
|
||||
if (botInfo->commands[j].command != cmd) {
|
||||
botInfo->commands[j].command = cmd;
|
||||
changedCommands = true;
|
||||
}
|
||||
if (botInfo->commands[j].setDescription(desc)) {
|
||||
changedCommands = true;
|
||||
}
|
||||
}
|
||||
++j;
|
||||
}
|
||||
while (j < botInfo->commands.size()) {
|
||||
botInfo->commands.pop_back();
|
||||
changedCommands = true;
|
||||
}
|
||||
|
||||
botInfo->inited = true;
|
||||
|
||||
if (changedCommands && App::main()) {
|
||||
App::main()->botCommandsChanged(this);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -258,13 +293,15 @@ void UserData::nameUpdated() {
|
||||
}
|
||||
|
||||
void UserData::madeAction() {
|
||||
if (botInfo || isServiceUser(id)) return;
|
||||
|
||||
int32 t = unixtime();
|
||||
if (onlineTill <= 0 && -onlineTill < t) {
|
||||
onlineTill = -t - SetOnlineAfterActivity;
|
||||
if (App::main()) App::main()->peerUpdated(this);
|
||||
App::markPeerUpdated(this);
|
||||
} else if (onlineTill > 0 && onlineTill < t + 1) {
|
||||
onlineTill = t + SetOnlineAfterActivity;
|
||||
if (App::main()) App::main()->peerUpdated(this);
|
||||
App::markPeerUpdated(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +311,7 @@ void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) {
|
||||
const MTPDchatPhoto d(p.c_chatPhoto());
|
||||
photo = ImagePtr(160, 160, d.vphoto_small, chatDefPhoto(colorIndex));
|
||||
photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex));
|
||||
if (phId) {
|
||||
if (phId != UnknownPeerPhotoId) {
|
||||
photoId = phId;
|
||||
}
|
||||
} break;
|
||||
@@ -433,16 +470,16 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||
if ((!data->user && !data->date) || button != Qt::LeftButton) return;
|
||||
|
||||
QString already = data->already(true);
|
||||
bool play = audioPlayer();
|
||||
bool play = App::hoveredLinkItem() && audioPlayer();
|
||||
if (!already.isEmpty() || (!data->data.isEmpty() && play)) {
|
||||
if (play) {
|
||||
AudioData *playing = 0;
|
||||
AudioMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &playingState);
|
||||
if (playing == data && playingState != AudioPlayerStopped) {
|
||||
audioPlayer()->pauseresume();
|
||||
if (playing.msgId == App::hoveredLinkItem()->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||
audioPlayer()->pauseresume(OverviewAudios);
|
||||
} else {
|
||||
audioPlayer()->play(data);
|
||||
audioPlayer()->play(AudioMsgId(data, App::hoveredLinkItem()->id));
|
||||
if (App::main()) App::main()->audioMarkRead(data);
|
||||
}
|
||||
} else {
|
||||
@@ -454,7 +491,7 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||
|
||||
if (data->status != FileReady) return;
|
||||
|
||||
bool mp3 = (data->mime == QLatin1String("audio/mp3"));
|
||||
bool mp3 = (data->mime == qstr("audio/mp3"));
|
||||
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false);
|
||||
if (!filename.isEmpty()) {
|
||||
data->openOnSave = 1;
|
||||
@@ -475,7 +512,7 @@ void AudioSaveLink::doSave(AudioData *data, bool forceSavingAs) {
|
||||
} else {
|
||||
QFileInfo alreadyInfo(already);
|
||||
QDir alreadyDir(already.isEmpty() ? QDir() : alreadyInfo.dir());
|
||||
bool mp3 = (data->mime == QLatin1String("audio/mp3"));
|
||||
bool mp3 = (data->mime == qstr("audio/mp3"));
|
||||
QString name = already.isEmpty() ? (mp3 ? qsl(".mp3") : qsl(".ogg")) : alreadyInfo.fileName();
|
||||
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), name, forceSavingAs, alreadyDir);
|
||||
if (!filename.isEmpty()) {
|
||||
@@ -536,13 +573,24 @@ QString AudioData::already(bool check) {
|
||||
return location.name;
|
||||
}
|
||||
|
||||
void DocumentOpenLink::onClick(Qt::MouseButton button) const {
|
||||
DocumentData *data = document();
|
||||
if (!data->date || button != Qt::LeftButton) return;
|
||||
void DocumentOpenLink::doOpen(DocumentData *data) {
|
||||
if (!data->date) return;
|
||||
|
||||
bool play = data->song() && App::hoveredLinkItem() && audioPlayer();
|
||||
QString already = data->already(true);
|
||||
if (!already.isEmpty()) {
|
||||
if (data->size < MediaViewImageSizeLimit) {
|
||||
if (!already.isEmpty() || (!data->data.isEmpty() && play)) {
|
||||
if (play) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
audioPlayer()->currentState(&playing, &playingState);
|
||||
if (playing.msgId == App::hoveredLinkItem()->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||
audioPlayer()->pauseresume(OverviewDocuments);
|
||||
} else {
|
||||
SongMsgId song(data, App::hoveredLinkItem()->id);
|
||||
audioPlayer()->play(song);
|
||||
if (App::main()) App::main()->documentPlayProgress(song);
|
||||
}
|
||||
} else if (data->size < MediaViewImageSizeLimit) {
|
||||
QImageReader reader(already);
|
||||
if (reader.canRead()) {
|
||||
if (reader.supportsAnimation() && reader.imageCount() > 1 && App::hoveredLinkItem()) {
|
||||
@@ -585,6 +633,11 @@ void DocumentOpenLink::onClick(Qt::MouseButton button) const {
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentOpenLink::onClick(Qt::MouseButton button) const {
|
||||
if (button != Qt::LeftButton) return;
|
||||
doOpen(document());
|
||||
}
|
||||
|
||||
void DocumentSaveLink::doSave(DocumentData *data, bool forceSavingAs) {
|
||||
if (!data->date) return;
|
||||
|
||||
@@ -637,7 +690,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) :
|
||||
id(id), type(FileDocument), duration(0), access(access), date(date), mime(mime), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0), sticker(0) {
|
||||
id(id), type(FileDocument), access(access), date(date), mime(mime), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0), _additional(0) {
|
||||
setattributes(attributes);
|
||||
location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||
}
|
||||
@@ -649,12 +702,17 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
|
||||
const MTPDdocumentAttributeImageSize &d(attributes[i].c_documentAttributeImageSize());
|
||||
dimensions = QSize(d.vw.v, d.vh.v);
|
||||
} break;
|
||||
case mtpc_documentAttributeAnimated: if (type == FileDocument || type == StickerDocument) type = AnimatedDocument; break;
|
||||
case mtpc_documentAttributeAnimated: if (type == FileDocument || type == StickerDocument) {
|
||||
type = AnimatedDocument;
|
||||
delete _additional;
|
||||
_additional = 0;
|
||||
} break;
|
||||
case mtpc_documentAttributeSticker: {
|
||||
const MTPDdocumentAttributeSticker &d(attributes[i].c_documentAttributeSticker());
|
||||
if (type == FileDocument) type = StickerDocument;
|
||||
if (type == StickerDocument && !sticker) sticker = new StickerData();
|
||||
if (sticker) {
|
||||
if (type == FileDocument) {
|
||||
type = StickerDocument;
|
||||
StickerData *sticker = new StickerData();
|
||||
_additional = sticker;
|
||||
sticker->alt = qs(d.valt);
|
||||
sticker->set = d.vstickerset;
|
||||
}
|
||||
@@ -662,17 +720,28 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
|
||||
case mtpc_documentAttributeVideo: {
|
||||
const MTPDdocumentAttributeVideo &d(attributes[i].c_documentAttributeVideo());
|
||||
type = VideoDocument;
|
||||
duration = d.vduration.v;
|
||||
// duration = d.vduration.v;
|
||||
dimensions = QSize(d.vw.v, d.vh.v);
|
||||
} break;
|
||||
case mtpc_documentAttributeAudio: {
|
||||
const MTPDdocumentAttributeAudio &d(attributes[i].c_documentAttributeAudio());
|
||||
type = AudioDocument;
|
||||
duration = d.vduration.v;
|
||||
type = SongDocument;
|
||||
SongData *song = new SongData();
|
||||
_additional = song;
|
||||
song->duration = d.vduration.v;
|
||||
song->title = qs(d.vtitle);
|
||||
song->performer = qs(d.vperformer);
|
||||
} break;
|
||||
case mtpc_documentAttributeFilename: name = qs(attributes[i].c_documentAttributeFilename().vfile_name); break;
|
||||
}
|
||||
}
|
||||
if (type == StickerDocument) {
|
||||
if (dimensions.width() <= 0 || dimensions.height() <= 0 || dimensions.width() > StickerMaxSize || dimensions.height() > StickerMaxSize || size > StickerInMemory) {
|
||||
type = FileDocument;
|
||||
delete _additional;
|
||||
_additional = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentData::save(const QString &toFile) {
|
||||
|
||||
@@ -106,6 +106,8 @@ struct PeerData {
|
||||
static const uint64 UserNoAccess = 0xFFFFFFFFFFFFFFFFULL;
|
||||
|
||||
class PeerLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(PeerLink)
|
||||
|
||||
public:
|
||||
PeerLink(PeerData *peer) : _peer(peer) {
|
||||
}
|
||||
@@ -118,11 +120,35 @@ private:
|
||||
PeerData *_peer;
|
||||
};
|
||||
|
||||
struct BotCommand {
|
||||
BotCommand(const QString &command, const QString &description) : command(command), description(description) {
|
||||
class BotCommand {
|
||||
public:
|
||||
BotCommand(const QString &command, const QString &description) : command(command), _description(description) {
|
||||
|
||||
}
|
||||
QString command, description;
|
||||
QString command;
|
||||
|
||||
bool setDescription(const QString &description) {
|
||||
if (_description != description) {
|
||||
_description = description;
|
||||
_descriptionText = Text();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const Text &descriptionText() const {
|
||||
if (_descriptionText.isEmpty() && !_description.isEmpty()) {
|
||||
_descriptionText.setText(st::mentionFont, _description, _textNameOptions);
|
||||
}
|
||||
return _descriptionText;
|
||||
}
|
||||
|
||||
private:
|
||||
QString _description;
|
||||
mutable Text _descriptionText;
|
||||
|
||||
};
|
||||
|
||||
struct BotInfo {
|
||||
BotInfo() : inited(false), readsAllHistory(false), cantJoinGroups(false), version(0), text(st::msgMinWidth) {
|
||||
}
|
||||
@@ -136,9 +162,11 @@ struct BotInfo {
|
||||
QString startToken, startGroupToken;
|
||||
};
|
||||
|
||||
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
|
||||
|
||||
struct PhotoData;
|
||||
struct UserData : public PeerData {
|
||||
UserData(const PeerId &id) : PeerData(id), photoId(0), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) {
|
||||
UserData(const PeerId &id) : PeerData(id), photoId(UnknownPeerPhotoId), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) {
|
||||
}
|
||||
void setPhoto(const MTPUserProfilePhoto &photo);
|
||||
void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username);
|
||||
@@ -167,9 +195,9 @@ struct UserData : public PeerData {
|
||||
};
|
||||
|
||||
struct ChatData : public PeerData {
|
||||
ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0), photoId(0) {
|
||||
ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0), photoId(UnknownPeerPhotoId) {
|
||||
}
|
||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = 0);
|
||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||
int32 count;
|
||||
int32 date;
|
||||
int32 version;
|
||||
@@ -234,6 +262,8 @@ struct PhotoData {
|
||||
};
|
||||
|
||||
class PhotoLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(PhotoLink)
|
||||
|
||||
public:
|
||||
PhotoLink(PhotoData *photo) : _photo(photo), _peer(0) {
|
||||
}
|
||||
@@ -313,6 +343,8 @@ struct VideoData {
|
||||
};
|
||||
|
||||
class VideoLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(VideoLink)
|
||||
|
||||
public:
|
||||
VideoLink(VideoData *video) : _video(video) {
|
||||
}
|
||||
@@ -325,6 +357,8 @@ private:
|
||||
};
|
||||
|
||||
class VideoSaveLink : public VideoLink {
|
||||
TEXT_LINK_CLASS(VideoSaveLink)
|
||||
|
||||
public:
|
||||
VideoSaveLink(VideoData *video) : VideoLink(video) {
|
||||
}
|
||||
@@ -333,6 +367,8 @@ public:
|
||||
};
|
||||
|
||||
class VideoOpenLink : public VideoLink {
|
||||
TEXT_LINK_CLASS(VideoOpenLink)
|
||||
|
||||
public:
|
||||
VideoOpenLink(VideoData *video) : VideoLink(video) {
|
||||
}
|
||||
@@ -340,6 +376,8 @@ public:
|
||||
};
|
||||
|
||||
class VideoCancelLink : public VideoLink {
|
||||
TEXT_LINK_CLASS(VideoCancelLink)
|
||||
|
||||
public:
|
||||
VideoCancelLink(VideoData *video) : VideoLink(video) {
|
||||
}
|
||||
@@ -399,7 +437,30 @@ struct AudioData {
|
||||
int32 md5[8];
|
||||
};
|
||||
|
||||
struct AudioMsgId {
|
||||
AudioMsgId() : audio(0), msgId(0) {
|
||||
}
|
||||
AudioMsgId(AudioData *audio, MsgId msgId) : audio(audio), msgId(msgId) {
|
||||
}
|
||||
operator bool() const {
|
||||
return audio;
|
||||
}
|
||||
AudioData *audio;
|
||||
MsgId msgId;
|
||||
};
|
||||
inline bool operator<(const AudioMsgId &a, const AudioMsgId &b) {
|
||||
return quintptr(a.audio) < quintptr(b.audio) || (quintptr(a.audio) == quintptr(b.audio) && a.msgId < b.msgId);
|
||||
}
|
||||
inline bool operator==(const AudioMsgId &a, const AudioMsgId &b) {
|
||||
return a.audio == b.audio && a.msgId == b.msgId;
|
||||
}
|
||||
inline bool operator!=(const AudioMsgId &a, const AudioMsgId &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
class AudioLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(AudioLink)
|
||||
|
||||
public:
|
||||
AudioLink(AudioData *audio) : _audio(audio) {
|
||||
}
|
||||
@@ -412,6 +473,8 @@ private:
|
||||
};
|
||||
|
||||
class AudioSaveLink : public AudioLink {
|
||||
TEXT_LINK_CLASS(AudioSaveLink)
|
||||
|
||||
public:
|
||||
AudioSaveLink(AudioData *audio) : AudioLink(audio) {
|
||||
}
|
||||
@@ -420,6 +483,8 @@ public:
|
||||
};
|
||||
|
||||
class AudioOpenLink : public AudioLink {
|
||||
TEXT_LINK_CLASS(AudioOpenLink)
|
||||
|
||||
public:
|
||||
AudioOpenLink(AudioData *audio) : AudioLink(audio) {
|
||||
}
|
||||
@@ -427,13 +492,26 @@ public:
|
||||
};
|
||||
|
||||
class AudioCancelLink : public AudioLink {
|
||||
TEXT_LINK_CLASS(AudioCancelLink)
|
||||
|
||||
public:
|
||||
AudioCancelLink(AudioData *audio) : AudioLink(audio) {
|
||||
}
|
||||
void onClick(Qt::MouseButton button) const;
|
||||
};
|
||||
|
||||
struct StickerData {
|
||||
enum DocumentType {
|
||||
FileDocument = 0,
|
||||
VideoDocument = 1,
|
||||
SongDocument = 2,
|
||||
StickerDocument = 3,
|
||||
AnimatedDocument = 4,
|
||||
};
|
||||
|
||||
struct DocumentAdditionalData {
|
||||
};
|
||||
|
||||
struct StickerData : public DocumentAdditionalData {
|
||||
StickerData() : set(MTP_inputStickerSetEmpty()) {
|
||||
}
|
||||
ImagePtr img;
|
||||
@@ -445,20 +523,20 @@ struct StickerData {
|
||||
StorageImageLocation loc; // doc thumb location
|
||||
};
|
||||
|
||||
enum DocumentType {
|
||||
FileDocument,
|
||||
VideoDocument,
|
||||
AudioDocument,
|
||||
StickerDocument,
|
||||
AnimatedDocument
|
||||
struct SongData : public DocumentAdditionalData {
|
||||
SongData() : duration(0) {
|
||||
}
|
||||
int32 duration;
|
||||
QString title, performer;
|
||||
};
|
||||
|
||||
struct DocumentData {
|
||||
DocumentData(const DocumentId &id, const uint64 &access = 0, int32 date = 0, const QVector<MTPDocumentAttribute> &attributes = QVector<MTPDocumentAttribute>(), const QString &mime = QString(), const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
void setattributes(const QVector<MTPDocumentAttribute> &attributes);
|
||||
|
||||
void forget() {
|
||||
thumb->forget();
|
||||
if (sticker) sticker->img->forget();
|
||||
if (sticker()) sticker()->img->forget();
|
||||
replyPreview->forget();
|
||||
}
|
||||
|
||||
@@ -488,15 +566,20 @@ struct DocumentData {
|
||||
loader = 0;
|
||||
}
|
||||
~DocumentData() {
|
||||
delete sticker;
|
||||
delete _additional;
|
||||
}
|
||||
|
||||
QString already(bool check = false);
|
||||
StickerData *sticker() {
|
||||
return (type == StickerDocument) ? static_cast<StickerData*>(_additional) : 0;
|
||||
}
|
||||
SongData *song() {
|
||||
return (type == SongDocument) ? static_cast<SongData*>(_additional) : 0;
|
||||
}
|
||||
|
||||
DocumentId id;
|
||||
DocumentType type;
|
||||
QSize dimensions;
|
||||
int32 duration;
|
||||
uint64 access;
|
||||
int32 date;
|
||||
QString name, mime;
|
||||
@@ -512,12 +595,35 @@ struct DocumentData {
|
||||
FileLocation location;
|
||||
|
||||
QByteArray data;
|
||||
StickerData *sticker;
|
||||
DocumentAdditionalData *_additional;
|
||||
|
||||
int32 md5[8];
|
||||
};
|
||||
|
||||
struct SongMsgId {
|
||||
SongMsgId() : song(0), msgId(0) {
|
||||
}
|
||||
SongMsgId(DocumentData *song, MsgId msgId) : song(song), msgId(msgId) {
|
||||
}
|
||||
operator bool() const {
|
||||
return song;
|
||||
}
|
||||
DocumentData *song;
|
||||
MsgId msgId;
|
||||
};
|
||||
inline bool operator<(const SongMsgId &a, const SongMsgId &b) {
|
||||
return quintptr(a.song) < quintptr(b.song) || (quintptr(a.song) == quintptr(b.song) && a.msgId < b.msgId);
|
||||
}
|
||||
inline bool operator==(const SongMsgId &a, const SongMsgId &b) {
|
||||
return a.song == b.song && a.msgId == b.msgId;
|
||||
}
|
||||
inline bool operator!=(const SongMsgId &a, const SongMsgId &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
class DocumentLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(DocumentLink)
|
||||
|
||||
public:
|
||||
DocumentLink(DocumentData *document) : _document(document) {
|
||||
}
|
||||
@@ -530,6 +636,8 @@ private:
|
||||
};
|
||||
|
||||
class DocumentSaveLink : public DocumentLink {
|
||||
TEXT_LINK_CLASS(DocumentSaveLink)
|
||||
|
||||
public:
|
||||
DocumentSaveLink(DocumentData *document) : DocumentLink(document) {
|
||||
}
|
||||
@@ -538,13 +646,18 @@ public:
|
||||
};
|
||||
|
||||
class DocumentOpenLink : public DocumentLink {
|
||||
TEXT_LINK_CLASS(DocumentOpenLink)
|
||||
|
||||
public:
|
||||
DocumentOpenLink(DocumentData *document) : DocumentLink(document) {
|
||||
}
|
||||
static void doOpen(DocumentData *document);
|
||||
void onClick(Qt::MouseButton button) const;
|
||||
};
|
||||
|
||||
class DocumentCancelLink : public DocumentLink {
|
||||
TEXT_LINK_CLASS(DocumentCancelLink)
|
||||
|
||||
public:
|
||||
DocumentCancelLink(DocumentData *document) : DocumentLink(document) {
|
||||
}
|
||||
@@ -558,9 +671,9 @@ enum WebPageType {
|
||||
WebPageArticle
|
||||
};
|
||||
inline WebPageType toWebPageType(const QString &type) {
|
||||
if (type == QLatin1String("photo")) return WebPagePhoto;
|
||||
if (type == QLatin1String("video")) return WebPageVideo;
|
||||
if (type == QLatin1String("profile")) return WebPageProfile;
|
||||
if (type == qstr("photo")) return WebPagePhoto;
|
||||
if (type == qstr("video")) return WebPageVideo;
|
||||
if (type == qstr("profile")) return WebPageProfile;
|
||||
return WebPageArticle;
|
||||
}
|
||||
|
||||
|
||||
@@ -199,6 +199,7 @@ private:
|
||||
};
|
||||
|
||||
#define qsl(s) QStringLiteral(s)
|
||||
#define qstr(s) QLatin1String(s, sizeof(s) - 1)
|
||||
|
||||
static const QRegularExpression::PatternOptions reMultiline(QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption);
|
||||
|
||||
@@ -247,7 +248,7 @@ enum DataBlockId {
|
||||
dbiLastUpdateCheck = 0x0d,
|
||||
dbiWindowPosition = 0x0e,
|
||||
dbiConnectionType = 0x0f,
|
||||
// 16 reserved
|
||||
// 0x10 reserved
|
||||
dbiDefaultAttach = 0x11,
|
||||
dbiCatsAndDogs = 0x12,
|
||||
dbiReplaceEmojis = 0x13,
|
||||
@@ -258,7 +259,7 @@ enum DataBlockId {
|
||||
dbiRecentEmojisOld = 0x18,
|
||||
dbiLoggedPhoneNumber = 0x19,
|
||||
dbiMutedPeers = 0x1a,
|
||||
// 27 reserved
|
||||
// 0x1b reserved
|
||||
dbiNotifyView = 0x1c,
|
||||
dbiSendToMenu = 0x1d,
|
||||
dbiCompressPastedImage = 0x1e,
|
||||
@@ -271,6 +272,8 @@ enum DataBlockId {
|
||||
dbiEmojiVariants = 0x25,
|
||||
dbiRecentStickers = 0x26,
|
||||
dbiDcOption = 0x27,
|
||||
dbiTryIPv6 = 0x28,
|
||||
dbiSongVolume = 0x29,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
|
||||
@@ -1426,7 +1426,7 @@ void Window::notifyShowNext(NotifyWindow *remove) {
|
||||
if (j == notifyWhenMaps.end()) {
|
||||
history->clearNotifications();
|
||||
i = notifyWaiters.erase(i);
|
||||
if (notifyHistory) notifyWaiter = notifyWaiters.find(notifyHistory);
|
||||
notifyWaiter = notifyHistory ? notifyWaiters.find(notifyHistory) : notifyWaiters.end();
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
@@ -1442,7 +1442,7 @@ void Window::notifyShowNext(NotifyWindow *remove) {
|
||||
if (!history->currentNotification()) {
|
||||
notifyWhenMaps.remove(history);
|
||||
i = notifyWaiters.erase(i);
|
||||
if (notifyHistory) notifyWaiter = notifyWaiters.find(notifyHistory);
|
||||
notifyWaiter = notifyHistory ? notifyWaiters.find(notifyHistory) : notifyWaiters.end();
|
||||
continue;
|
||||
}
|
||||
uint64 when = i.value().when;
|
||||
@@ -1712,10 +1712,10 @@ void Window::sendPaths() {
|
||||
}
|
||||
}
|
||||
|
||||
void Window::mediaOverviewUpdated(PeerData *peer) {
|
||||
if (main) main->mediaOverviewUpdated(peer);
|
||||
void Window::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
if (main) main->mediaOverviewUpdated(peer, type);
|
||||
if (!_mediaView || _mediaView->isHidden()) return;
|
||||
_mediaView->mediaOverviewUpdated(peer);
|
||||
_mediaView->mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
|
||||
void Window::documentUpdated(DocumentData *doc) {
|
||||
|
||||
@@ -226,7 +226,7 @@ public:
|
||||
|
||||
void sendPaths();
|
||||
|
||||
void mediaOverviewUpdated(PeerData *peer);
|
||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||
void documentUpdated(DocumentData *doc);
|
||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.8.29</string>
|
||||
<string>0.8.39</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
|
||||
@@ -96,6 +96,7 @@ SOURCES += \
|
||||
./SourceFiles/overviewwidget.cpp \
|
||||
./SourceFiles/passcodewidget.cpp \
|
||||
./SourceFiles/profilewidget.cpp \
|
||||
./SourceFiles/playerwidget.cpp \
|
||||
./SourceFiles/localimageloader.cpp \
|
||||
./SourceFiles/localstorage.cpp \
|
||||
./SourceFiles/logs.cpp \
|
||||
@@ -182,6 +183,7 @@ HEADERS += \
|
||||
./SourceFiles/overviewwidget.h \
|
||||
./SourceFiles/passcodewidget.h \
|
||||
./SourceFiles/profilewidget.h \
|
||||
./SourceFiles/playerwidget.h \
|
||||
./SourceFiles/localimageloader.h \
|
||||
./SourceFiles/localstorage.h \
|
||||
./SourceFiles/logs.h \
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -903,6 +903,18 @@
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_autoupdater.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\playerwidget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Deploy\moc_playerwidget.cpp">
|
||||
<Filter>Generated Files\Deploy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_playerwidget.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_playerwidget.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\stdafx.h">
|
||||
@@ -1198,6 +1210,9 @@
|
||||
<CustomBuild Include="SourceFiles\autoupdater.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SourceFiles\playerwidget.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="SourceFiles\art\icon256.ico" />
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
07AF95F51AFD03B90060B057 /* qrc_telegram_mac.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07AF95F31AFD03B90060B057 /* qrc_telegram_mac.cpp */; };
|
||||
07AF95F91AFD03C80060B057 /* telegram_emojis.qrc in Resources */ = {isa = PBXBuildFile; fileRef = 07AF95F71AFD03C80060B057 /* telegram_emojis.qrc */; };
|
||||
07AF95FA1AFD03C80060B057 /* telegram_mac.qrc in Resources */ = {isa = PBXBuildFile; fileRef = 07AF95F81AFD03C80060B057 /* telegram_mac.qrc */; };
|
||||
07B604321B46A0EC00CA29FE /* playerwidget.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07B604301B46A0EC00CA29FE /* playerwidget.cpp */; };
|
||||
07B604351B46A20900CA29FE /* moc_playerwidget.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07B604341B46A20900CA29FE /* moc_playerwidget.cpp */; };
|
||||
07BE850F1A2093C9008ACB9F /* localstorage.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07BE850D1A2093C9008ACB9F /* localstorage.cpp */; };
|
||||
07BE85121A20961F008ACB9F /* moc_localstorage.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07BE85111A20961F008ACB9F /* moc_localstorage.cpp */; };
|
||||
07C4753B1967DF1C00CAAFE9 /* switcher.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07C475391967DF1C00CAAFE9 /* switcher.cpp */; };
|
||||
@@ -305,6 +307,9 @@
|
||||
07AF95F31AFD03B90060B057 /* qrc_telegram_mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qrc_telegram_mac.cpp; path = GeneratedFiles/qrc_telegram_mac.cpp; sourceTree = SOURCE_ROOT; };
|
||||
07AF95F71AFD03C80060B057 /* telegram_emojis.qrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = telegram_emojis.qrc; path = SourceFiles/telegram_emojis.qrc; sourceTree = SOURCE_ROOT; };
|
||||
07AF95F81AFD03C80060B057 /* telegram_mac.qrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = telegram_mac.qrc; path = SourceFiles/telegram_mac.qrc; sourceTree = SOURCE_ROOT; };
|
||||
07B604301B46A0EC00CA29FE /* playerwidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = playerwidget.cpp; path = SourceFiles/playerwidget.cpp; sourceTree = SOURCE_ROOT; };
|
||||
07B604311B46A0EC00CA29FE /* playerwidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = playerwidget.h; path = SourceFiles/playerwidget.h; sourceTree = SOURCE_ROOT; };
|
||||
07B604341B46A20900CA29FE /* moc_playerwidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_playerwidget.cpp; path = GeneratedFiles/Debug/moc_playerwidget.cpp; sourceTree = SOURCE_ROOT; };
|
||||
07BE850D1A2093C9008ACB9F /* localstorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = localstorage.cpp; path = SourceFiles/localstorage.cpp; sourceTree = SOURCE_ROOT; };
|
||||
07BE850E1A2093C9008ACB9F /* localstorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = localstorage.h; path = SourceFiles/localstorage.h; sourceTree = SOURCE_ROOT; };
|
||||
07BE85111A20961F008ACB9F /* moc_localstorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_localstorage.cpp; path = GeneratedFiles/Debug/moc_localstorage.cpp; sourceTree = SOURCE_ROOT; };
|
||||
@@ -914,6 +919,7 @@
|
||||
07A69330199277BA0099CB9F /* mediaview.cpp */,
|
||||
0732E4A7199E262300D50FE7 /* overviewwidget.cpp */,
|
||||
07DE929F1AA4923200A18F6F /* passcodewidget.cpp */,
|
||||
07B604301B46A0EC00CA29FE /* playerwidget.cpp */,
|
||||
CF32DF59C7823E4F3397EF3C /* profilewidget.cpp */,
|
||||
5A7F88F9C7F08D3DDE6EEF6B /* localimageloader.cpp */,
|
||||
07BE850D1A2093C9008ACB9F /* localstorage.cpp */,
|
||||
@@ -952,6 +958,7 @@
|
||||
07A69331199277BA0099CB9F /* mediaview.h */,
|
||||
0732E4A8199E262300D50FE7 /* overviewwidget.h */,
|
||||
07DE92A21AA4924400A18F6F /* passcodewidget.h */,
|
||||
07B604311B46A0EC00CA29FE /* playerwidget.h */,
|
||||
220B97F8F62C720E6059A64B /* profilewidget.h */,
|
||||
AD0C395D671BC024083A5FC7 /* localimageloader.h */,
|
||||
07BE850E1A2093C9008ACB9F /* localstorage.h */,
|
||||
@@ -1106,6 +1113,7 @@
|
||||
801973D3334D0FCA849CF485 /* Debug */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
07B604341B46A20900CA29FE /* moc_playerwidget.cpp */,
|
||||
07C759711B1F7E2800662169 /* moc_autoupdater.cpp */,
|
||||
0710CA041B0B9404001B4272 /* moc_stickersetbox.cpp */,
|
||||
0755AEDA1AD12A80004D738A /* moc_abstractbox.cpp */,
|
||||
@@ -1610,6 +1618,7 @@
|
||||
06EABCC49D2EEE4076322BE7 /* moc_mtp.cpp in Compile Sources */,
|
||||
0755AEDE1AD12A80004D738A /* moc_intropwdcheck.cpp in Compile Sources */,
|
||||
07DE92AA1AA4928200A18F6F /* moc_autolockbox.cpp in Compile Sources */,
|
||||
07B604351B46A20900CA29FE /* moc_playerwidget.cpp in Compile Sources */,
|
||||
8F6F5D7F82036331E8C6DAE6 /* moc_mtpConnection.cpp in Compile Sources */,
|
||||
B780F9E21269259B90A1F32A /* moc_mtpDC.cpp in Compile Sources */,
|
||||
07080BCF1A43588C00741A51 /* lang_auto.cpp in Compile Sources */,
|
||||
@@ -1638,6 +1647,7 @@
|
||||
60CB4898955209B665E7B07D /* moc_twidget.cpp in Compile Sources */,
|
||||
7062978F12EEA525893A5E6F /* moc_aboutbox.cpp in Compile Sources */,
|
||||
E8B28580819B882A5964561A /* moc_addcontactbox.cpp in Compile Sources */,
|
||||
07B604321B46A0EC00CA29FE /* playerwidget.cpp in Compile Sources */,
|
||||
D6874C00733283846ACA9AB2 /* moc_confirmbox.cpp in Compile Sources */,
|
||||
ED2557A57C6782721DC494AF /* moc_connectionbox.cpp in Compile Sources */,
|
||||
5FC914F652D1B16FDA8F0634 /* moc_contactsbox.cpp in Compile Sources */,
|
||||
@@ -1701,7 +1711,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.29;
|
||||
CURRENT_PROJECT_VERSION = 0.8.39;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@@ -1719,7 +1729,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 0.8.29;
|
||||
CURRENT_PROJECT_VERSION = 0.8.39;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||
@@ -1745,10 +1755,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.29;
|
||||
CURRENT_PROJECT_VERSION = 0.8.39;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.29;
|
||||
DYLIB_CURRENT_VERSION = 0.8.39;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
@@ -1888,10 +1898,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.29;
|
||||
CURRENT_PROJECT_VERSION = 0.8.39;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.29;
|
||||
DYLIB_CURRENT_VERSION = 0.8.39;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
|
||||
@@ -33,7 +33,7 @@ check: first
|
||||
|
||||
compilers: GeneratedFiles/qrc_telegram.cpp GeneratedFiles/qrc_telegram_emojis.cpp GeneratedFiles/qrc_telegram_mac.cpp GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_autoupdater.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp\
|
||||
GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp\
|
||||
GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp\
|
||||
GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_playerwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp\
|
||||
GeneratedFiles/Debug/moc_passcodewidget.cpp\
|
||||
GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp\
|
||||
GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp\
|
||||
@@ -99,9 +99,9 @@ GeneratedFiles/qrc_telegram_mac.cpp: SourceFiles/telegram_mac.qrc \
|
||||
SourceFiles/art/osxtray.png
|
||||
/usr/local/Qt-5.4.0/bin/rcc -name telegram_mac SourceFiles/telegram_mac.qrc -o GeneratedFiles/qrc_telegram_mac.cpp
|
||||
|
||||
compiler_moc_header_make_all: GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_autoupdater.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_abstractbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_sessionsbox.cpp GeneratedFiles/Debug/moc_stickersetbox.cpp GeneratedFiles/Debug/moc_usernamebox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_intropwdcheck.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
||||
compiler_moc_header_make_all: GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_autoupdater.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_playerwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_abstractbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_sessionsbox.cpp GeneratedFiles/Debug/moc_stickersetbox.cpp GeneratedFiles/Debug/moc_usernamebox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_intropwdcheck.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
||||
compiler_moc_header_clean:
|
||||
-$(DEL_FILE) GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_autoupdater.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_abstractbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_sessionsbox.cpp GeneratedFiles/Debug/moc_stickersetbox.cpp GeneratedFiles/Debug/moc_usernamedbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_intropwdcheck.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
||||
-$(DEL_FILE) GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_autoupdater.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_playerwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_abstractbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_sessionsbox.cpp GeneratedFiles/Debug/moc_stickersetbox.cpp GeneratedFiles/Debug/moc_usernamedbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_intropwdcheck.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
||||
GeneratedFiles/Debug/moc_apiwrap.cpp: SourceFiles/types.h \
|
||||
SourceFiles/logs.h \
|
||||
SourceFiles/apiwrap.h
|
||||
@@ -179,6 +179,9 @@ GeneratedFiles/Debug/moc_mediaview.cpp: SourceFiles/mediaview.h
|
||||
GeneratedFiles/Debug/moc_overviewwidget.cpp: SourceFiles/overviewwidget.h
|
||||
/usr/local/Qt-5.4.0/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.4.0/mkspecs/macx-clang -I. -I/usr/local/Qt-5.4.0/include/QtGui/5.4.0/QtGui -I/usr/local/Qt-5.4.0/include/QtCore/5.4.0/QtCore -I/usr/local/Qt-5.4.0/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.4.0/include -I/usr/local/Qt-5.4.0/include/QtMultimedia -I/usr/local/Qt-5.4.0/include/QtWidgets -I/usr/local/Qt-5.4.0/include/QtNetwork -I/usr/local/Qt-5.4.0/include/QtGui -I/usr/local/Qt-5.4.0/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/overviewwidget.h -o GeneratedFiles/Debug/moc_overviewwidget.cpp
|
||||
|
||||
GeneratedFiles/Debug/moc_playerwidget.cpp: SourceFiles/playerwidget.h
|
||||
/usr/local/Qt-5.4.0/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.4.0/mkspecs/macx-clang -I. -I/usr/local/Qt-5.4.0/include/QtGui/5.4.0/QtGui -I/usr/local/Qt-5.4.0/include/QtCore/5.4.0/QtCore -I/usr/local/Qt-5.4.0/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.4.0/include -I/usr/local/Qt-5.4.0/include/QtMultimedia -I/usr/local/Qt-5.4.0/include/QtWidgets -I/usr/local/Qt-5.4.0/include/QtNetwork -I/usr/local/Qt-5.4.0/include/QtGui -I/usr/local/Qt-5.4.0/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/playerwidget.h -o GeneratedFiles/Debug/moc_playerwidget.cpp
|
||||
|
||||
GeneratedFiles/Debug/moc_profilewidget.cpp: SourceFiles/profilewidget.h
|
||||
/usr/local/Qt-5.4.0/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.4.0/mkspecs/macx-clang -I. -I/usr/local/Qt-5.4.0/include/QtGui/5.4.0/QtGui -I/usr/local/Qt-5.4.0/include/QtCore/5.4.0/QtCore -I/usr/local/Qt-5.4.0/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.4.0/include -I/usr/local/Qt-5.4.0/include/QtMultimedia -I/usr/local/Qt-5.4.0/include/QtWidgets -I/usr/local/Qt-5.4.0/include/QtNetwork -I/usr/local/Qt-5.4.0/include/QtGui -I/usr/local/Qt-5.4.0/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/profilewidget.h -o GeneratedFiles/Debug/moc_profilewidget.cpp
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
echo 8029 0.8.29 1
|
||||
# AppVersion AppVersionStr DevChannel
|
||||
echo 0.8 8039 0.8.39 1
|
||||
# AppVersionStrMajor AppVersion AppVersionStr DevChannel
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,35 +1,36 @@
|
||||
diff --git a/qtbase/mkspecs/win32-msvc2013/qmake.conf b/qtbase/mkspecs/win32-msvc2013/qmake.conf
|
||||
index 535904a..6d0e9b9 100644
|
||||
--- a/qtbase/mkspecs/win32-msvc2013/qmake.conf
|
||||
+++ b/qtbase/mkspecs/win32-msvc2013/qmake.conf
|
||||
@@ -25,9 +25,9 @@ QMAKE_YACCFLAGS = -d
|
||||
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t -FS
|
||||
diff --git a/qtbase/mkspecs/common/msvc-desktop.conf b/qtbase/mkspecs/common/msvc-desktop.conf
|
||||
index e638af6..e44ee5e 100644
|
||||
--- a/qtbase/mkspecs/common/msvc-desktop.conf
|
||||
+++ b/qtbase/mkspecs/common/msvc-desktop.conf
|
||||
@@ -28,9 +28,9 @@ QMAKE_YACCFLAGS = -d
|
||||
QMAKE_CFLAGS = -nologo -Zc:wchar_t
|
||||
QMAKE_CFLAGS_WARN_ON = -W3
|
||||
QMAKE_CFLAGS_WARN_OFF = -W0
|
||||
-QMAKE_CFLAGS_RELEASE = -O2 -MD -Zc:strictStrings
|
||||
-QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi -Zc:strictStrings
|
||||
-QMAKE_CFLAGS_RELEASE = -O2 -MD
|
||||
-QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
|
||||
-QMAKE_CFLAGS_DEBUG = -Zi -MDd
|
||||
+QMAKE_CFLAGS_RELEASE = -O2 -MT -Zc:strictStrings
|
||||
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi -Zc:strictStrings
|
||||
+QMAKE_CFLAGS_RELEASE = -O2 -MT
|
||||
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
|
||||
+QMAKE_CFLAGS_DEBUG = -Zi -MTd
|
||||
QMAKE_CFLAGS_YACC =
|
||||
QMAKE_CFLAGS_LTCG = -GL
|
||||
QMAKE_CFLAGS_MP = -MP
|
||||
QMAKE_CFLAGS_SSE2 = -arch:SSE2
|
||||
diff --git a/qtbase/qmake/generators/mac/pbuilder_pbx.cpp b/qtbase/qmake/generators/mac/pbuilder_pbx.cpp
|
||||
index 0ff4250..9ed555c 100644
|
||||
index 81bb068..a0fe016 100644
|
||||
--- a/qtbase/qmake/generators/mac/pbuilder_pbx.cpp
|
||||
+++ b/qtbase/qmake/generators/mac/pbuilder_pbx.cpp
|
||||
@@ -1445,11 +1445,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
plist_in_text = plist_in_text.replace("@TYPEINFO@",
|
||||
@@ -1500,11 +1500,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
plist_in_text.replace("@TYPEINFO@",
|
||||
(project->isEmpty("QMAKE_PKGINFO_TYPEINFO")
|
||||
? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString()));
|
||||
- QFile plist_out_file("Info.plist");
|
||||
- QFile plist_out_file(Option::output_dir + "/Info.plist");
|
||||
- if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
+ QString plist_dir;
|
||||
+ if (!project->isEmpty("PLIST_DIR"))
|
||||
+ plist_dir = project->first("PLIST_DIR").toQString();
|
||||
+ QString plist_in_filename = QFileInfo(plist_in_file).fileName();
|
||||
+ QFile plist_out_file(plist_dir + plist_in_filename);
|
||||
if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
+ QFile plist_out_file(Option::output_dir + "/" + plist_dir + plist_in_filename);
|
||||
+ if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream plist_out(&plist_out_file);
|
||||
plist_out << plist_in_text;
|
||||
- t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";\n";
|
||||
@@ -38,10 +39,10 @@ index 0ff4250..9ed555c 100644
|
||||
}
|
||||
}
|
||||
diff --git a/qtbase/qmake/generators/makefile.cpp b/qtbase/qmake/generators/makefile.cpp
|
||||
index bf9a9d8..0216f5c 100644
|
||||
index 4a03faf..2c18c48 100644
|
||||
--- a/qtbase/qmake/generators/makefile.cpp
|
||||
+++ b/qtbase/qmake/generators/makefile.cpp
|
||||
@@ -206,7 +206,7 @@ MakefileGenerator::initOutPaths()
|
||||
@@ -167,7 +167,7 @@ MakefileGenerator::initOutPaths()
|
||||
v["PRECOMPILED_DIR"] = v["OBJECTS_DIR"];
|
||||
static const char * const dirs[] = { "OBJECTS_DIR", "DESTDIR",
|
||||
"SUBLIBS_DIR", "DLLDESTDIR",
|
||||
@@ -51,7 +52,7 @@ index bf9a9d8..0216f5c 100644
|
||||
const ProKey dkey(dirs[x]);
|
||||
if (v[dkey].isEmpty())
|
||||
diff --git a/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c b/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c
|
||||
index 1987f27..6b36e4f 100644
|
||||
index 0907653..96f6e19 100644
|
||||
--- a/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c
|
||||
+++ b/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c
|
||||
@@ -101,7 +101,7 @@ for (p = string; length-- > 0; p++)
|
||||
@@ -63,11 +64,24 @@ index 1987f27..6b36e4f 100644
|
||||
{
|
||||
/* High surrogate. Must be a followed by a low surrogate. */
|
||||
if (length == 0)
|
||||
diff --git a/qtbase/src/corelib/kernel/qobjectdefs.h b/qtbase/src/corelib/kernel/qobjectdefs.h
|
||||
index 4d01264..fd3854f 100644
|
||||
--- a/qtbase/src/corelib/kernel/qobjectdefs.h
|
||||
+++ b/qtbase/src/corelib/kernel/qobjectdefs.h
|
||||
@@ -142,7 +142,7 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {}
|
||||
# define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN
|
||||
#endif
|
||||
|
||||
-#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
|
||||
+#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306 && false
|
||||
# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
|
||||
#else
|
||||
# define Q_OBJECT_NO_OVERRIDE_WARNING
|
||||
diff --git a/qtbase/src/corelib/tools/qunicodetables.cpp b/qtbase/src/corelib/tools/qunicodetables.cpp
|
||||
index 072e8ad..2bf3bfd 100644
|
||||
index 73dce81..76c6933 100644
|
||||
--- a/qtbase/src/corelib/tools/qunicodetables.cpp
|
||||
+++ b/qtbase/src/corelib/tools/qunicodetables.cpp
|
||||
@@ -5360,7 +5360,7 @@ static const Properties uc_properties[] = {
|
||||
@@ -5839,7 +5839,7 @@ static const Properties uc_properties[] = {
|
||||
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 11 },
|
||||
{ 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
|
||||
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 11 },
|
||||
@@ -77,7 +91,7 @@ index 072e8ad..2bf3bfd 100644
|
||||
{ 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
|
||||
{ 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
|
||||
diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
|
||||
index 21c1a2f..f293ef9 100644
|
||||
index f124ced..eb78a13 100644
|
||||
--- a/qtbase/src/gui/image/qbmphandler.cpp
|
||||
+++ b/qtbase/src/gui/image/qbmphandler.cpp
|
||||
@@ -212,6 +212,9 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
||||
@@ -101,7 +115,7 @@ index 21c1a2f..f293ef9 100644
|
||||
uchar rgb[4];
|
||||
int rgb_len = t == BMP_OLD ? 3 : 4;
|
||||
diff --git a/qtbase/src/gui/kernel/qplatformdialoghelper.h b/qtbase/src/gui/kernel/qplatformdialoghelper.h
|
||||
index e0730cd..00fccad 100644
|
||||
index 8b2b988..2d1cdd9 100644
|
||||
--- a/qtbase/src/gui/kernel/qplatformdialoghelper.h
|
||||
+++ b/qtbase/src/gui/kernel/qplatformdialoghelper.h
|
||||
@@ -363,6 +363,7 @@ public:
|
||||
@@ -113,7 +127,7 @@ index e0730cd..00fccad 100644
|
||||
virtual void selectNameFilter(const QString &filter) = 0;
|
||||
virtual QString selectedNameFilter() const = 0;
|
||||
diff --git a/qtbase/src/gui/painting/qpaintengine_p.h b/qtbase/src/gui/painting/qpaintengine_p.h
|
||||
index 312320c..5e82318 100644
|
||||
index c58662e..468d671 100644
|
||||
--- a/qtbase/src/gui/painting/qpaintengine_p.h
|
||||
+++ b/qtbase/src/gui/painting/qpaintengine_p.h
|
||||
@@ -79,8 +79,18 @@ public:
|
||||
@@ -123,8 +137,8 @@ index 312320c..5e82318 100644
|
||||
- else
|
||||
- systemClip = systemTransform.map(systemClip);
|
||||
+ else {
|
||||
+ // Transform the system clip region back from device pixels to device-independent pixels before
|
||||
+ // applying systemTransform, which already has transform from device-independent pixels to device pixels
|
||||
+// Transform the system clip region back from device pixels to device-independent pixels before
|
||||
+// applying systemTransform, which already has transform from device-independent pixels to device pixels
|
||||
+#ifdef Q_OS_MAC
|
||||
+ QTransform scaleTransform;
|
||||
+ const qreal invDevicePixelRatio = 1. / pdev->devicePixelRatio();
|
||||
@@ -138,32 +152,30 @@ index 312320c..5e82318 100644
|
||||
|
||||
// Make sure we're inside the viewport.
|
||||
diff --git a/qtbase/src/gui/text/qtextlayout.cpp b/qtbase/src/gui/text/qtextlayout.cpp
|
||||
index 1ac50d3..3c88caa 100644
|
||||
index 7da3e84..0829250 100644
|
||||
--- a/qtbase/src/gui/text/qtextlayout.cpp
|
||||
+++ b/qtbase/src/gui/text/qtextlayout.cpp
|
||||
@@ -643,7 +643,10 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
|
||||
@@ -643,6 +643,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
|
||||
while (oldPos < len && !attributes[oldPos].graphemeBoundary)
|
||||
oldPos++;
|
||||
} else {
|
||||
- if (oldPos < len && d->atWordSeparator(oldPos)) {
|
||||
+ while (oldPos < len && d->atSpace(oldPos))
|
||||
+ while (oldPos < len && attributes[oldPos].whiteSpace)
|
||||
+ oldPos++;
|
||||
+
|
||||
+ if (oldPos < len && d->atWordSeparator(oldPos)) {
|
||||
if (oldPos < len && d->atWordSeparator(oldPos)) {
|
||||
oldPos++;
|
||||
while (oldPos < len && d->atWordSeparator(oldPos))
|
||||
oldPos++;
|
||||
@@ -651,8 +654,6 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
|
||||
while (oldPos < len && !d->atSpace(oldPos) && !d->atWordSeparator(oldPos))
|
||||
while (oldPos < len && !attributes[oldPos].whiteSpace && !d->atWordSeparator(oldPos))
|
||||
oldPos++;
|
||||
}
|
||||
- while (oldPos < len && d->atSpace(oldPos))
|
||||
- while (oldPos < len && attributes[oldPos].whiteSpace)
|
||||
- oldPos++;
|
||||
}
|
||||
|
||||
return oldPos;
|
||||
diff --git a/qtbase/src/gui/text/qtextlayout.h b/qtbase/src/gui/text/qtextlayout.h
|
||||
index 1e0ab9b..47972d3 100644
|
||||
index 47dcd38..64c3810 100644
|
||||
--- a/qtbase/src/gui/text/qtextlayout.h
|
||||
+++ b/qtbase/src/gui/text/qtextlayout.h
|
||||
@@ -186,6 +186,8 @@ private:
|
||||
@@ -176,27 +188,29 @@ index 1e0ab9b..47972d3 100644
|
||||
|
||||
|
||||
diff --git a/qtbase/src/network/socket/qnativesocketengine_win.cpp b/qtbase/src/network/socket/qnativesocketengine_win.cpp
|
||||
index f5943d6..f7787c3 100644
|
||||
index 72f85c8..a1c2e08 100644
|
||||
--- a/qtbase/src/network/socket/qnativesocketengine_win.cpp
|
||||
+++ b/qtbase/src/network/socket/qnativesocketengine_win.cpp
|
||||
@@ -703,6 +703,12 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
|
||||
@@ -685,7 +685,13 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
|
||||
errorDetected = true;
|
||||
break;
|
||||
}
|
||||
- if (value == WSAEADDRNOTAVAIL) {
|
||||
+ if (value == WSAENETUNREACH) {
|
||||
+ setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString);
|
||||
+ socketState = QAbstractSocket::UnconnectedState;
|
||||
+ errorDetected = true;
|
||||
+ break;
|
||||
+ }
|
||||
if (value == WSAEADDRNOTAVAIL) {
|
||||
+ if (value == WSAEADDRNOTAVAIL) {
|
||||
setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
errorDetected = true;
|
||||
diff --git a/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
|
||||
index 43903ac..efa7014 100644
|
||||
index 65cdabd..190683e 100644
|
||||
--- a/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
|
||||
+++ b/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
|
||||
@@ -213,6 +213,78 @@ void QBasicFontDatabase::releaseHandle(void *handle)
|
||||
@@ -198,6 +198,78 @@ void QBasicFontDatabase::releaseHandle(void *handle)
|
||||
|
||||
extern FT_Library qt_getFreetype();
|
||||
|
||||
@@ -275,12 +289,12 @@ index 43903ac..efa7014 100644
|
||||
QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file, QSupportedWritingSystems *supportedWritingSystems)
|
||||
{
|
||||
FT_Library library = qt_getFreetype();
|
||||
@@ -224,9 +296,9 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
|
||||
@@ -209,9 +281,9 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
|
||||
FT_Face face;
|
||||
FT_Error error;
|
||||
if (!fontData.isEmpty()) {
|
||||
- error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
|
||||
+ error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
|
||||
+ error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
|
||||
} else {
|
||||
- error = FT_New_Face(library, file.constData(), index, &face);
|
||||
+ error = __ft_New_Face(library, file.constData(), index, &face);
|
||||
@@ -288,10 +302,10 @@ index 43903ac..efa7014 100644
|
||||
if (error != FT_Err_Ok) {
|
||||
qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
|
||||
diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
|
||||
index 5dec1d0..f4d6fcd 100644
|
||||
index 112bb8e..9f1df70 100644
|
||||
--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
|
||||
+++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
|
||||
@@ -341,6 +341,15 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
@@ -373,6 +373,15 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
return;
|
||||
|
||||
familyName = QString::fromUtf8((const char *)value);
|
||||
@@ -307,7 +321,7 @@ index 5dec1d0..f4d6fcd 100644
|
||||
|
||||
slant_value = FC_SLANT_ROMAN;
|
||||
weight_value = FC_WEIGHT_REGULAR;
|
||||
@@ -742,6 +751,15 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
|
||||
@@ -781,6 +790,15 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
|
||||
FcChar8 *fam = 0;
|
||||
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
|
||||
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
|
||||
@@ -324,10 +338,10 @@ index 5dec1d0..f4d6fcd 100644
|
||||
}
|
||||
populateFromPattern(pattern);
|
||||
diff --git a/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
index 9f2ff10..fe87ca1 100644
|
||||
index be70092..1594dac 100644
|
||||
--- a/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
+++ b/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
@@ -257,6 +257,10 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
@@ -263,6 +263,10 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
|
||||
fd->foundryName = QStringLiteral("CoreText");
|
||||
fd->familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
|
||||
@@ -339,10 +353,10 @@ index 9f2ff10..fe87ca1 100644
|
||||
fd->weight = QFont::Normal;
|
||||
fd->style = QFont::StyleNormal;
|
||||
diff --git a/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
index 9f7609f..5df1514 100644
|
||||
index f3a0216..643ebdd 100644
|
||||
--- a/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
+++ b/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
@@ -216,7 +216,7 @@ static void cleanupCocoaApplicationDelegate()
|
||||
@@ -210,7 +210,7 @@ QT_END_NAMESPACE
|
||||
if (reflectionDelegate) {
|
||||
if ([reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)])
|
||||
return [reflectionDelegate applicationShouldTerminate:sender];
|
||||
@@ -352,25 +366,18 @@ index 9f7609f..5df1514 100644
|
||||
|
||||
if ([self canQuit]) {
|
||||
diff --git a/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
index e449fd3..7f7bd24 100644
|
||||
index 713758c..9c695aa 100644
|
||||
--- a/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
+++ b/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
@@ -102,7 +102,7 @@ QT_USE_NAMESPACE
|
||||
@@ -94,6 +94,7 @@ QT_USE_NAMESPACE
|
||||
QCocoaSystemTrayIcon *systray;
|
||||
NSStatusItem *item;
|
||||
QCocoaMenu *menu;
|
||||
- bool menuVisible;
|
||||
+ bool menuVisible, iconSelected;
|
||||
+ bool menuVisible, iconSelected;
|
||||
QIcon icon;
|
||||
QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
|
||||
}
|
||||
@@ -202,13 +202,11 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
|
||||
m_sys->item->icon = icon;
|
||||
|
||||
- const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible;
|
||||
-
|
||||
// The reccomended maximum title bar icon height is 18 points
|
||||
@@ -197,7 +198,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
// (device independent pixels). The menu height on past and
|
||||
// current OS X versions is 22 points. Provide some future-proofing
|
||||
// by deriving the icon height from the menu height.
|
||||
@@ -379,32 +386,51 @@ index e449fd3..7f7bd24 100644
|
||||
const int menuHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
|
||||
const int maxImageHeight = menuHeight - padding;
|
||||
|
||||
@@ -218,7 +216,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
@@ -207,8 +208,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
// devicePixelRatio for the "best" screen on the system.
|
||||
qreal devicePixelRatio = qApp->devicePixelRatio();
|
||||
const int maxPixmapHeight = maxImageHeight * devicePixelRatio;
|
||||
- const QIcon::Mode mode = menuVisible ? QIcon::Selected : QIcon::Normal;
|
||||
+ const QIcon::Mode mode = m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal;
|
||||
+ const QIcon::Mode mode = m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal;
|
||||
QSize selectedSize;
|
||||
Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
|
||||
- Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes())) {
|
||||
+ Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
|
||||
// Select a pixmap based on the height. We want the largest pixmap
|
||||
@@ -381,6 +379,7 @@ QT_END_NAMESPACE
|
||||
// with a height smaller or equal to maxPixmapHeight. The pixmap
|
||||
// may rectangular; assume it has a reasonable size. If there is
|
||||
@@ -224,9 +226,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
|
||||
// Handle SVG icons, which do not return anything for availableSizes().
|
||||
if (!selectedSize.isValid())
|
||||
- selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight));
|
||||
+ selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight), mode);
|
||||
|
||||
- QPixmap pixmap = icon.pixmap(selectedSize);
|
||||
+ QPixmap pixmap = icon.pixmap(selectedSize, mode);
|
||||
|
||||
// Draw a low-resolution icon if there is not enough pixels for a retina
|
||||
// icon. This prevents showing a small icon on retina displays.
|
||||
@@ -373,6 +375,10 @@ QT_END_NAMESPACE
|
||||
Q_UNUSED(notification);
|
||||
down = NO;
|
||||
|
||||
+ parent->iconSelected = false;
|
||||
parent->systray->updateIcon(parent->icon);
|
||||
parent->menuVisible = false;
|
||||
+ parent->systray->updateIcon(parent->icon);
|
||||
+ parent->menuVisible = false;
|
||||
+
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
@@ -393,6 +392,7 @@ QT_END_NAMESPACE
|
||||
@@ -381,6 +387,9 @@ QT_END_NAMESPACE
|
||||
down = YES;
|
||||
int clickCount = [mouseEvent clickCount];
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
+ parent->iconSelected = (clickCount != 2) && parent->menu;
|
||||
parent->systray->updateIcon(parent->icon);
|
||||
+
|
||||
+ parent->iconSelected = (clickCount != 2) && parent->menu;
|
||||
+ parent->systray->updateIcon(parent->icon);
|
||||
|
||||
if (clickCount == 2) {
|
||||
@@ -411,6 +411,10 @@ QT_END_NAMESPACE
|
||||
[self menuTrackingDone:nil];
|
||||
@@ -398,6 +407,10 @@ QT_END_NAMESPACE
|
||||
-(void)mouseUp:(NSEvent *)mouseEvent
|
||||
{
|
||||
Q_UNUSED(mouseEvent);
|
||||
@@ -415,7 +441,7 @@ index e449fd3..7f7bd24 100644
|
||||
[self menuTrackingDone:nil];
|
||||
}
|
||||
|
||||
@@ -422,6 +426,10 @@ QT_END_NAMESPACE
|
||||
@@ -409,6 +422,10 @@ QT_END_NAMESPACE
|
||||
-(void)rightMouseUp:(NSEvent *)mouseEvent
|
||||
{
|
||||
Q_UNUSED(mouseEvent);
|
||||
@@ -426,20 +452,36 @@ index e449fd3..7f7bd24 100644
|
||||
[self menuTrackingDone:nil];
|
||||
}
|
||||
|
||||
@@ -437,7 +445,7 @@ QT_END_NAMESPACE
|
||||
@@ -424,7 +441,7 @@ QT_END_NAMESPACE
|
||||
}
|
||||
|
||||
-(void)drawRect:(NSRect)rect {
|
||||
- [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down];
|
||||
+ [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
|
||||
+ [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
|
||||
[super drawRect:rect];
|
||||
}
|
||||
@end
|
||||
@@ -437,6 +454,7 @@ QT_END_NAMESPACE
|
||||
if (self) {
|
||||
item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
|
||||
menu = 0;
|
||||
+ menuVisible = false;
|
||||
systray = sys;
|
||||
imageCell = [[QNSImageView alloc] initWithParent:self];
|
||||
[item setView: imageCell];
|
||||
@@ -481,6 +499,7 @@ QT_END_NAMESPACE
|
||||
selector:@selector(menuTrackingDone:)
|
||||
name:NSMenuDidEndTrackingNotification
|
||||
object:m];
|
||||
+ menuVisible = true;
|
||||
[item popUpStatusItemMenu: m];
|
||||
}
|
||||
}
|
||||
diff --git a/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm b/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
index 6656212..486fda0 100644
|
||||
index 92fc66a..d18884a 100644
|
||||
--- a/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
+++ b/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
@@ -175,7 +175,7 @@ static void selectNextKeyWindow(NSWindow *currentKeyWindow)
|
||||
@@ -142,7 +142,7 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
if (!self.window.delegate)
|
||||
return; // Already detached, pending NSAppKitDefined event
|
||||
|
||||
@@ -448,7 +490,7 @@ index 6656212..486fda0 100644
|
||||
NSPoint loc = [theEvent locationInWindow];
|
||||
NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
|
||||
NSRect contentFrame = [[self.window contentView] frame];
|
||||
@@ -918,6 +918,14 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
|
||||
@@ -924,6 +924,14 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
|
||||
[m_nsWindow setRepresentedFilename: fi.exists() ? QCFString::toNSString(filePath) : @""];
|
||||
}
|
||||
|
||||
@@ -463,7 +505,7 @@ index 6656212..486fda0 100644
|
||||
void QCocoaWindow::setWindowIcon(const QIcon &icon)
|
||||
{
|
||||
QCocoaAutoReleasePool pool;
|
||||
@@ -933,7 +941,8 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
|
||||
@@ -939,7 +947,8 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
|
||||
if (icon.isNull()) {
|
||||
[iconButton setImage:nil];
|
||||
} else {
|
||||
@@ -474,33 +516,34 @@ index 6656212..486fda0 100644
|
||||
[iconButton setImage:image];
|
||||
[image release];
|
||||
diff --git a/qtbase/src/plugins/platforms/cocoa/qnsview.mm b/qtbase/src/plugins/platforms/cocoa/qnsview.mm
|
||||
index 6993407..0357bf4 100644
|
||||
index d44cdb3..cfc8705 100644
|
||||
--- a/qtbase/src/plugins/platforms/cocoa/qnsview.mm
|
||||
+++ b/qtbase/src/plugins/platforms/cocoa/qnsview.mm
|
||||
@@ -1321,7 +1321,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
@@ -1348,7 +1348,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
|
||||
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
|
||||
// On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
|
||||
- if (phase == NSEventPhaseMayBegin)
|
||||
+ if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan)
|
||||
- if (phase == NSEventPhaseMayBegin) {
|
||||
+ if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan) {
|
||||
m_scrolling = true;
|
||||
ph = Qt::ScrollBegin;
|
||||
} else
|
||||
#endif
|
||||
@@ -1451,6 +1451,9 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
}
|
||||
@@ -1489,6 +1489,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
&& qtKey == Qt::Key_Period) {
|
||||
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
|
||||
return YES;
|
||||
+ } else if ([nsevent modifierFlags] & NSControlKeyMask && (qtKey == Qt::Key_Tab || qtKey == Qt::Key_Backtab)) {
|
||||
+ } else if ([nsevent modifierFlags] & NSControlKeyMask
|
||||
+ && (qtKey == Qt::Key_Tab || qtKey == Qt::Key_Backtab)) {
|
||||
+ [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
|
||||
+ return YES;
|
||||
}
|
||||
}
|
||||
return [super performKeyEquivalent:nsevent];
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
index f1f472b..97819dd 100644
|
||||
index da0ba27..1d42b79 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
+++ b/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
@@ -710,6 +710,8 @@ public:
|
||||
@@ -713,6 +713,8 @@ public:
|
||||
QList<QUrl> selectedFiles() const;
|
||||
void setSelectedFiles(const QList<QUrl> &);
|
||||
QString selectedFile() const;
|
||||
@@ -509,7 +552,7 @@ index f1f472b..97819dd 100644
|
||||
|
||||
private:
|
||||
class Data : public QSharedData {
|
||||
@@ -717,6 +719,7 @@ private:
|
||||
@@ -720,6 +722,7 @@ private:
|
||||
QUrl directory;
|
||||
QString selectedNameFilter;
|
||||
QList<QUrl> selectedFiles;
|
||||
@@ -517,7 +560,7 @@ index f1f472b..97819dd 100644
|
||||
QMutex mutex;
|
||||
};
|
||||
QExplicitlySharedDataPointer<Data> m_data;
|
||||
@@ -770,6 +773,20 @@ inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &ur
|
||||
@@ -773,6 +776,20 @@ inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &ur
|
||||
m_data->selectedFiles = urls;
|
||||
}
|
||||
|
||||
@@ -538,7 +581,7 @@ index f1f472b..97819dd 100644
|
||||
inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o)
|
||||
{
|
||||
QMutexLocker (&m_data->mutex);
|
||||
@@ -893,6 +910,7 @@ public:
|
||||
@@ -896,6 +913,7 @@ public:
|
||||
// Return the result for tracking in OnFileOk(). Differs from selection for
|
||||
// example by appended default suffixes, etc.
|
||||
virtual QList<QUrl> dialogResult() const = 0;
|
||||
@@ -546,21 +589,25 @@ index f1f472b..97819dd 100644
|
||||
|
||||
inline void onFolderChange(IShellItem *);
|
||||
inline void onSelectionChange();
|
||||
@@ -1286,7 +1304,12 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel
|
||||
|
||||
void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const
|
||||
@@ -1332,8 +1350,15 @@ void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const
|
||||
{
|
||||
- m_fileDialog->SetFileName((wchar_t*)fileName.utf16());
|
||||
+ QString file = QDir::toNativeSeparators(fileName);
|
||||
+ int lastBackSlash = file.lastIndexOf(QChar::fromLatin1('\\'));
|
||||
+ if (lastBackSlash >= 0) {
|
||||
+ file = file.mid(lastBackSlash + 1);
|
||||
// Hack to prevent CLSIDs from being set as file name due to
|
||||
// QFileDialogPrivate::initialSelection() being QString-based.
|
||||
- if (!isClsid(fileName))
|
||||
- m_fileDialog->SetFileName((wchar_t*)fileName.utf16());
|
||||
+ if (!isClsid(fileName))
|
||||
+ {
|
||||
+ QString file = QDir::toNativeSeparators(fileName);
|
||||
+ int lastBackSlash = file.lastIndexOf(QChar::fromLatin1('\\'));
|
||||
+ if (lastBackSlash >= 0) {
|
||||
+ file = file.mid(lastBackSlash + 1);
|
||||
+ }
|
||||
+ m_fileDialog->SetFileName((wchar_t*)file.utf16());;
|
||||
+ }
|
||||
+ m_fileDialog->SetFileName((wchar_t*)file.utf16());;
|
||||
}
|
||||
|
||||
// Return the index of the selected filter, accounting for QFileDialog
|
||||
@@ -1356,6 +1379,7 @@ bool QWindowsNativeFileDialogBase::onFileOk()
|
||||
@@ -1403,6 +1428,7 @@ bool QWindowsNativeFileDialogBase::onFileOk()
|
||||
{
|
||||
// Store selected files as GetResults() returns invalid data after the dialog closes.
|
||||
m_data.setSelectedFiles(dialogResult());
|
||||
@@ -568,7 +615,7 @@ index f1f472b..97819dd 100644
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1484,6 +1508,7 @@ public:
|
||||
@@ -1531,6 +1557,7 @@ public:
|
||||
QWindowsNativeFileDialogBase(data) {}
|
||||
virtual QList<QUrl> selectedFiles() const;
|
||||
virtual QList<QUrl> dialogResult() const;
|
||||
@@ -576,7 +623,7 @@ index f1f472b..97819dd 100644
|
||||
|
||||
private:
|
||||
inline IFileOpenDialog *openFileDialog() const
|
||||
@@ -1499,6 +1524,54 @@ QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
|
||||
@@ -1546,6 +1573,54 @@ QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -631,7 +678,7 @@ index f1f472b..97819dd 100644
|
||||
QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const
|
||||
{
|
||||
QList<QUrl> result;
|
||||
@@ -1562,6 +1635,7 @@ public:
|
||||
@@ -1609,6 +1684,7 @@ public:
|
||||
virtual QUrl directory() const Q_DECL_OVERRIDE;
|
||||
virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
|
||||
virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
|
||||
@@ -639,7 +686,7 @@ index f1f472b..97819dd 100644
|
||||
virtual void setFilter() Q_DECL_OVERRIDE;
|
||||
virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE;
|
||||
virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
|
||||
@@ -1655,6 +1729,11 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
|
||||
@@ -1702,6 +1778,11 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
|
||||
return m_data.selectedFiles();
|
||||
}
|
||||
|
||||
@@ -651,7 +698,7 @@ index f1f472b..97819dd 100644
|
||||
void QWindowsFileDialogHelper::setFilter()
|
||||
{
|
||||
qCDebug(lcQpaDialogs) << __FUNCTION__;
|
||||
@@ -1945,6 +2024,7 @@ public:
|
||||
@@ -1992,6 +2073,7 @@ public:
|
||||
virtual QUrl directory() const Q_DECL_OVERRIDE;
|
||||
virtual void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
|
||||
virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
|
||||
@@ -659,7 +706,7 @@ index f1f472b..97819dd 100644
|
||||
virtual void setFilter() Q_DECL_OVERRIDE {}
|
||||
virtual void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
|
||||
virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
|
||||
@@ -1988,6 +2068,11 @@ QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
|
||||
@@ -2035,6 +2117,11 @@ QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
|
||||
return m_data.selectedFiles();
|
||||
}
|
||||
|
||||
@@ -671,55 +718,11 @@ index f1f472b..97819dd 100644
|
||||
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
|
||||
{
|
||||
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp b/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp
|
||||
index ff9ad18..3fd0848 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp
|
||||
+++ b/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp
|
||||
@@ -537,17 +537,16 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer,
|
||||
Q_ASSERT(vk > 0 && vk < 256);
|
||||
int code = 0;
|
||||
QChar unicodeBuffer[5];
|
||||
- // While key combinations containing alt and ctrl might trigger the third assignment of a key
|
||||
- // (for example "alt+ctrl+q" causes '@' on a German layout), ToUnicode often does not return the
|
||||
- // wanted character if only the ctrl modifier is used. Thus we unset this modifier temporarily
|
||||
- // if it is not used together with alt.
|
||||
- const unsigned char controlState = kbdBuffer[VK_MENU] ? 0 : kbdBuffer[VK_CONTROL];
|
||||
- if (controlState)
|
||||
- kbdBuffer[VK_CONTROL] = 0;
|
||||
- int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
|
||||
- if (controlState)
|
||||
- kbdBuffer[VK_CONTROL] = controlState;
|
||||
- if (res)
|
||||
+ int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
|
||||
+ // When Ctrl modifier is used ToUnicode does not return correct values. In order to assign the
|
||||
+ // right key the control modifier is removed for just that function if the previous call failed.
|
||||
+ if (res == 0 && kbdBuffer[VK_CONTROL]) {
|
||||
+ const unsigned char controlState = kbdBuffer[VK_CONTROL];
|
||||
+ kbdBuffer[VK_CONTROL] = 0;
|
||||
+ res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
|
||||
+ kbdBuffer[VK_CONTROL] = controlState;
|
||||
+ }
|
||||
+ if (res)
|
||||
code = unicodeBuffer[0].toUpper().unicode();
|
||||
|
||||
// Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
|
||||
@@ -833,7 +832,10 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
|
||||
|
||||
const int qtKey = CmdTbl[cmd];
|
||||
sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
|
||||
- return true;
|
||||
+ // QTBUG-43343: Make sure to return false if Qt does not handle the key, otherwise,
|
||||
+ // the keys are not passed to the active media player.
|
||||
+ const QKeySequence sequence(Qt::Modifier(state) + qtKey);
|
||||
+ return QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(sequence);
|
||||
#else
|
||||
Q_UNREACHABLE();
|
||||
return false;
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
index 8a80729..16fda26 100644
|
||||
index 543c081..d80429b 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
+++ b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
@@ -943,7 +943,7 @@ void QWindowsWindow::destroyWindow()
|
||||
@@ -973,7 +973,7 @@ void QWindowsWindow::destroyWindow()
|
||||
// Clear any transient child relationships as Windows will otherwise destroy them (QTBUG-35499, QTBUG-36666)
|
||||
if (QWindow *transientChild = findTransientChild(window()))
|
||||
if (QWindowsWindow *tw = QWindowsWindow::baseWindowOf(transientChild))
|
||||
@@ -728,7 +731,7 @@ index 8a80729..16fda26 100644
|
||||
QWindowsContext *context = QWindowsContext::instance();
|
||||
if (context->windowUnderMouse() == window())
|
||||
context->clearWindowUnderMouse();
|
||||
@@ -1144,11 +1144,24 @@ void QWindowsWindow::updateTransientParent() const
|
||||
@@ -1178,11 +1178,24 @@ void QWindowsWindow::updateTransientParent() const
|
||||
if (const QWindowsWindow *tw = QWindowsWindow::baseWindowOf(tp))
|
||||
if (!tw->testFlag(WithinDestroy)) // Prevent destruction by parent window (QTBUG-35499, QTBUG-36666)
|
||||
newTransientParent = tw->handle();
|
||||
@@ -755,10 +758,10 @@ index 8a80729..16fda26 100644
|
||||
{
|
||||
// QWidget-attribute Qt::WA_ShowWithoutActivating .
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowswindow.h b/qtbase/src/plugins/platforms/windows/qwindowswindow.h
|
||||
index 71debf2..4fa2e5d 100644
|
||||
index fff90b4..71d060b 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowswindow.h
|
||||
+++ b/qtbase/src/plugins/platforms/windows/qwindowswindow.h
|
||||
@@ -268,6 +268,7 @@ private:
|
||||
@@ -273,6 +273,7 @@ private:
|
||||
inline void setWindowState_sys(Qt::WindowState newState);
|
||||
inline void setParent_sys(const QPlatformWindow *parent);
|
||||
inline void updateTransientParent() const;
|
||||
@@ -767,10 +770,10 @@ index 71debf2..4fa2e5d 100644
|
||||
inline bool isDropSiteEnabled() const { return m_dropTarget != 0; }
|
||||
void setDropSiteEnabled(bool enabled);
|
||||
diff --git a/qtbase/src/widgets/dialogs/qfiledialog.cpp b/qtbase/src/widgets/dialogs/qfiledialog.cpp
|
||||
index 6065ad0..03fad7a 100644
|
||||
index a9d5574..ea8aa43 100644
|
||||
--- a/qtbase/src/widgets/dialogs/qfiledialog.cpp
|
||||
+++ b/qtbase/src/widgets/dialogs/qfiledialog.cpp
|
||||
@@ -1219,6 +1219,14 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
|
||||
@@ -1199,6 +1199,14 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
|
||||
return files;
|
||||
}
|
||||
|
||||
@@ -782,10 +785,10 @@ index 6065ad0..03fad7a 100644
|
||||
+ return QByteArray();
|
||||
+}
|
||||
+
|
||||
QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesToFix) const
|
||||
QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &filesToFix) const
|
||||
{
|
||||
QStringList files;
|
||||
@@ -1282,6 +1290,13 @@ QStringList QFileDialog::selectedFiles() const
|
||||
@@ -1262,6 +1270,13 @@ QStringList QFileDialog::selectedFiles() const
|
||||
return files;
|
||||
}
|
||||
|
||||
@@ -800,10 +803,10 @@ index 6065ad0..03fad7a 100644
|
||||
Returns a list of urls containing the selected files in the dialog.
|
||||
If no files are selected, or the mode is not ExistingFiles or
|
||||
diff --git a/qtbase/src/widgets/dialogs/qfiledialog.h b/qtbase/src/widgets/dialogs/qfiledialog.h
|
||||
index 70e498a..b13e8b2 100644
|
||||
index 95209bc..0dca0ef 100644
|
||||
--- a/qtbase/src/widgets/dialogs/qfiledialog.h
|
||||
+++ b/qtbase/src/widgets/dialogs/qfiledialog.h
|
||||
@@ -103,6 +103,7 @@ public:
|
||||
@@ -106,6 +106,7 @@ public:
|
||||
|
||||
void selectFile(const QString &filename);
|
||||
QStringList selectedFiles() const;
|
||||
@@ -812,7 +815,7 @@ index 70e498a..b13e8b2 100644
|
||||
void selectUrl(const QUrl &url);
|
||||
QList<QUrl> selectedUrls() const;
|
||||
diff --git a/qtbase/src/widgets/dialogs/qfiledialog_p.h b/qtbase/src/widgets/dialogs/qfiledialog_p.h
|
||||
index cc2f481..cf70355 100644
|
||||
index f610e46..16fa44e 100644
|
||||
--- a/qtbase/src/widgets/dialogs/qfiledialog_p.h
|
||||
+++ b/qtbase/src/widgets/dialogs/qfiledialog_p.h
|
||||
@@ -123,6 +123,7 @@ public:
|
||||
@@ -820,10 +823,10 @@ index cc2f481..cf70355 100644
|
||||
QStringList typedFiles() const;
|
||||
QList<QUrl> userSelectedFiles() const;
|
||||
+ QByteArray userSelectedRemoteContent() const;
|
||||
QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const;
|
||||
QStringList addDefaultSuffixToFiles(const QStringList &filesToFix) const;
|
||||
QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
|
||||
bool removeDirectory(const QString &path);
|
||||
@@ -250,6 +251,7 @@ public:
|
||||
@@ -256,6 +257,7 @@ public:
|
||||
QUrl directory_sys() const;
|
||||
void selectFile_sys(const QUrl &filename);
|
||||
QList<QUrl> selectedFiles_sys() const;
|
||||
@@ -831,7 +834,7 @@ index cc2f481..cf70355 100644
|
||||
void setFilter_sys();
|
||||
void selectNameFilter_sys(const QString &filter);
|
||||
QString selectedNameFilter_sys() const;
|
||||
@@ -387,6 +389,13 @@ inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
|
||||
@@ -393,6 +395,13 @@ inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
|
||||
return QList<QUrl>();
|
||||
}
|
||||
|
||||
@@ -846,95 +849,54 @@ index cc2f481..cf70355 100644
|
||||
{
|
||||
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
|
||||
diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
|
||||
index 315d615..e99b1c3 100644
|
||||
index e701eb0..1bdaff5 100644
|
||||
--- a/qtbase/src/widgets/kernel/qwidget.cpp
|
||||
+++ b/qtbase/src/widgets/kernel/qwidget.cpp
|
||||
@@ -8674,7 +8674,7 @@ bool QWidget::event(QEvent *event)
|
||||
@@ -8683,7 +8683,7 @@ bool QWidget::event(QEvent *event)
|
||||
case QEvent::KeyPress: {
|
||||
QKeyEvent *k = (QKeyEvent *)event;
|
||||
bool res = false;
|
||||
- if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
|
||||
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))) { //### Add MetaModifier?
|
||||
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))) { //### Add MetaModifier?
|
||||
if (k->key() == Qt::Key_Backtab
|
||||
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
|
||||
res = focusNextPrevChild(false);
|
||||
diff --git a/qtbase/src/widgets/util/qsystemtrayicon.cpp b/qtbase/src/widgets/util/qsystemtrayicon.cpp
|
||||
index 7d04cab..53c2856 100644
|
||||
index dc2737c..aa9bc91 100644
|
||||
--- a/qtbase/src/widgets/util/qsystemtrayicon.cpp
|
||||
+++ b/qtbase/src/widgets/util/qsystemtrayicon.cpp
|
||||
@@ -710,7 +710,9 @@ void QSystemTrayIconPrivate::updateMenu_sys_qpa()
|
||||
menu->setPlatformMenu(platformMenu);
|
||||
}
|
||||
@@ -711,6 +711,8 @@ void QSystemTrayIconPrivate::updateMenu_sys_qpa()
|
||||
if (menu) {
|
||||
addPlatformMenu(menu);
|
||||
qpa_sys->updateMenu(menu->platformMenu());
|
||||
- }
|
||||
+ } else {
|
||||
+ qpa_sys->updateMenu(0);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
void QSystemTrayIconPrivate::updateToolTip_sys_qpa()
|
||||
diff --git a/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp b/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
index e6385ba..8e1543e 100644
|
||||
index 759e41a..fbd3064 100644
|
||||
--- a/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
+++ b/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
@@ -1870,7 +1870,7 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
|
||||
|
||||
if (unknown && !isReadOnly()) {
|
||||
@@ -1884,7 +1884,7 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
|
||||
&& event->modifiers() != Qt::ControlModifier
|
||||
&& event->modifiers() != (Qt::ControlModifier | Qt::ShiftModifier)) {
|
||||
QString t = event->text();
|
||||
- if (!t.isEmpty() && t.at(0).isPrint()) {
|
||||
+ if (!t.isEmpty() && (t.at(0).isPrint() || t.at(0).unicode() == 0x200C || t.at(0).unicode() == 0x200D)) {
|
||||
+ if (!t.isEmpty() && (t.at(0).isPrint() || t.at(0).unicode() == 0x200C || t.at(0).unicode() == 0x200D)) {
|
||||
insert(t);
|
||||
#ifndef QT_NO_COMPLETER
|
||||
complete(event->key());
|
||||
diff --git a/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp b/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
index dfec6a1..a1be4a1 100644
|
||||
index faa63cb..f3de539 100644
|
||||
--- a/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
+++ b/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
@@ -1340,7 +1340,7 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
||||
process:
|
||||
{
|
||||
@@ -1348,7 +1348,7 @@ process:
|
||||
return;
|
||||
}
|
||||
QString text = e->text();
|
||||
- if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) {
|
||||
+ if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t') || text.at(0).unicode() == 0x200C || text.at(0).unicode() == 0x200D)) {
|
||||
+ if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t') || text.at(0).unicode() == 0x200C || text.at(0).unicode() == 0x200D)) {
|
||||
if (overwriteMode
|
||||
// no need to call deleteChar() if we have a selection, insertText
|
||||
// does it already
|
||||
diff --git a/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c b/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c
|
||||
index ea0254d..93d9dc4 100644
|
||||
--- a/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c
|
||||
+++ b/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c
|
||||
@@ -12,7 +12,6 @@
|
||||
// Authors: Vikas Arora (vikaas.arora@gmail.com)
|
||||
// Jyrki Alakuijala (jyrki@google.com)
|
||||
|
||||
-#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "./alphai.h"
|
||||
#include "./vp8li.h"
|
||||
@@ -740,6 +739,7 @@ static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
|
||||
const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
|
||||
const int mask = hdr->huffman_mask_;
|
||||
assert(htree_group != NULL);
|
||||
+ assert(pos < end);
|
||||
assert(last_row <= height);
|
||||
assert(Is8bOptimizable(hdr));
|
||||
|
||||
@@ -830,6 +830,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
||||
(hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
|
||||
const int mask = hdr->huffman_mask_;
|
||||
assert(htree_group != NULL);
|
||||
+ assert(src < src_end);
|
||||
assert(src_last <= src_end);
|
||||
|
||||
while (!br->eos_ && src < src_last) {
|
||||
@@ -1294,6 +1295,10 @@ int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) {
|
||||
assert(dec->action_ == READ_DATA);
|
||||
assert(last_row <= dec->height_);
|
||||
|
||||
+ if (dec->last_pixel_ == dec->width_ * dec->height_) {
|
||||
+ return 1; // Done
|
||||
+ }
|
||||
+
|
||||
// Decode (with special row processing).
|
||||
return alph_dec->use_8b_decode ?
|
||||
DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_,
|
||||
@@ -1,60 +1,59 @@
|
||||
#
|
||||
# qmake configuration for win32-msvc2013
|
||||
#
|
||||
# Written for Microsoft Visual C++ 2013
|
||||
# qmake configuration for Microsoft Visual Studio C/C++ Compiler
|
||||
# This mkspec is used for all win32-msvcXXXX specs
|
||||
#
|
||||
|
||||
MAKEFILE_GENERATOR = MSBUILD
|
||||
isEmpty(MSC_VER)|isEmpty(MSVC_VER): error("Source mkspec must set both MSC_VER and MSVC_VER.")
|
||||
|
||||
#
|
||||
# Baseline: Visual Studio 2005 (8.0), VC++ 14.0
|
||||
#
|
||||
|
||||
MAKEFILE_GENERATOR = MSVC.NET
|
||||
QMAKE_PLATFORM = win32
|
||||
QMAKE_COMPILER = msvc
|
||||
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
|
||||
DEFINES += UNICODE WIN32
|
||||
MSVC_VER = 12.0
|
||||
QMAKE_COMPILER_DEFINES += _MSC_VER=1800 _WIN32
|
||||
QMAKE_COMPILER_DEFINES += _MSC_VER=$$MSC_VER _WIN32
|
||||
contains(QMAKE_TARGET.arch, x86_64) {
|
||||
DEFINES += WIN64
|
||||
QMAKE_COMPILER_DEFINES += _WIN64
|
||||
}
|
||||
|
||||
QMAKE_COMPILER = msvc
|
||||
|
||||
QMAKE_CC = cl
|
||||
QMAKE_LEX = flex
|
||||
QMAKE_LEXFLAGS =
|
||||
QMAKE_YACC = byacc
|
||||
QMAKE_YACCFLAGS = -d
|
||||
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t -FS
|
||||
QMAKE_CFLAGS = -nologo -Zc:wchar_t
|
||||
QMAKE_CFLAGS_WARN_ON = -W3
|
||||
QMAKE_CFLAGS_WARN_OFF = -W0
|
||||
QMAKE_CFLAGS_RELEASE = -O2 -MT -Zc:strictStrings
|
||||
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi -Zc:strictStrings
|
||||
QMAKE_CFLAGS_RELEASE = -O2 -MT
|
||||
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
|
||||
QMAKE_CFLAGS_DEBUG = -Zi -MTd
|
||||
QMAKE_CFLAGS_YACC =
|
||||
QMAKE_CFLAGS_LTCG = -GL
|
||||
QMAKE_CFLAGS_MP = -MP
|
||||
QMAKE_CFLAGS_SSE2 = -arch:SSE2
|
||||
QMAKE_CFLAGS_SSE3 = -arch:SSE2
|
||||
QMAKE_CFLAGS_SSSE3 = -arch:SSE2
|
||||
QMAKE_CFLAGS_SSE4_1 = -arch:SSE2
|
||||
QMAKE_CFLAGS_SSE4_2 = -arch:SSE2
|
||||
QMAKE_CFLAGS_AVX = -arch:AVX
|
||||
QMAKE_CFLAGS_AVX2 = -arch:AVX
|
||||
|
||||
QMAKE_CXX = $$QMAKE_CC
|
||||
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
|
||||
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189
|
||||
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189 -w44996
|
||||
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
|
||||
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
|
||||
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
|
||||
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
|
||||
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
|
||||
QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
|
||||
QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP
|
||||
QMAKE_CXXFLAGS_STL_ON = -EHsc
|
||||
QMAKE_CXXFLAGS_STL_OFF =
|
||||
QMAKE_CXXFLAGS_RTTI_ON = -GR
|
||||
QMAKE_CXXFLAGS_RTTI_OFF =
|
||||
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc
|
||||
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0
|
||||
QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
|
||||
|
||||
QMAKE_INCDIR =
|
||||
|
||||
@@ -70,8 +69,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT
|
||||
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
|
||||
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO
|
||||
QMAKE_LFLAGS_DEBUG = /DEBUG
|
||||
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
|
||||
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
|
||||
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
|
||||
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS
|
||||
QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
|
||||
QMAKE_LFLAGS_DLL = /DLL
|
||||
QMAKE_LFLAGS_LTCG = /LTCG
|
||||
@@ -91,9 +90,58 @@ QMAKE_IDL = midl
|
||||
QMAKE_LIB = lib /NOLOGO
|
||||
QMAKE_RC = rc
|
||||
|
||||
include(../common/shell-win32.conf)
|
||||
|
||||
VCPROJ_EXTENSION = .vcxproj
|
||||
VCPROJ_EXTENSION = .vcproj
|
||||
VCSOLUTION_EXTENSION = .sln
|
||||
VCPROJ_KEYWORD = Qt4VSv1.0
|
||||
load(qt_config)
|
||||
|
||||
#
|
||||
# Version-specific changes
|
||||
#
|
||||
greaterThan(MSC_VER, 1499) {
|
||||
# Visual Studio 2008 (9.0) / Visual C++ 15.0 and up
|
||||
QMAKE_CFLAGS_MP = -MP
|
||||
QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP
|
||||
}
|
||||
|
||||
greaterThan(MSC_VER, 1599) {
|
||||
# Visual Studio 2010 (10.0) / Visual C++ 16.0 and up
|
||||
MAKEFILE_GENERATOR = MSBUILD
|
||||
|
||||
QMAKE_CFLAGS_AVX = -arch:AVX
|
||||
QMAKE_CFLAGS_AVX2 = -arch:AVX
|
||||
|
||||
VCPROJ_EXTENSION = .vcxproj
|
||||
}
|
||||
|
||||
greaterThan(MSC_VER, 1699) {
|
||||
# Visual Studio 2012 (11.0) / Visual C++ 17.0 and up
|
||||
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0
|
||||
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
|
||||
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
|
||||
QT_CONFIG += c++11
|
||||
CONFIG += c++11
|
||||
}
|
||||
|
||||
greaterThan(MSC_VER, 1799) {
|
||||
# Visual Studio 2013 (12.0) / Visual C++ 18.0 and up
|
||||
QMAKE_CFLAGS += -FS
|
||||
QMAKE_CXXFLAGS += -FS
|
||||
|
||||
equals(MSC_VER, 1800) {
|
||||
QMAKE_CFLAGS_RELEASE += -Zc:strictStrings
|
||||
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -Zc:strictStrings
|
||||
QMAKE_CXXFLAGS_RELEASE += -Zc:strictStrings
|
||||
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += -Zc:strictStrings
|
||||
}
|
||||
}
|
||||
|
||||
greaterThan(MSC_VER, 1899) {
|
||||
# Visual Studio 2015 (14.0) / Visual C++ 19.0 and up
|
||||
QMAKE_CFLAGS += -Zc:strictStrings
|
||||
QMAKE_CFLAGS_WARN_ON += -w44456 -w44457 -w44458
|
||||
QMAKE_CFLAGS_AVX2 = -arch:AVX2
|
||||
QMAKE_CXXFLAGS += -Zc:strictStrings
|
||||
QMAKE_CXXFLAGS_WARN_ON += -w44456 -w44457 -w44458
|
||||
}
|
||||
|
||||
unset(MSC_VER)
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the qmake application of the Qt Toolkit.
|
||||
**
|
||||
@@ -10,9 +10,9 @@
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
@@ -23,8 +23,8 @@
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
@@ -105,7 +105,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
{
|
||||
if(project->isActiveConfig("generate_pbxbuild_makefile")) {
|
||||
QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
|
||||
qmake_getpwd());
|
||||
FileFixifyToIndir);
|
||||
QFile mkwrapf(mkwrap);
|
||||
if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
debug_msg(1, "pbuilder: Creating file: %s", mkwrap.toLatin1().constData());
|
||||
@@ -151,7 +151,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
subdir += Option::dir_sep;
|
||||
tmp = subdir + tmp;
|
||||
}
|
||||
QFileInfo fi(fileInfo(Option::fixPathToLocalOS(tmp, true)));
|
||||
QFileInfo fi(fileInfo(Option::normalizePath(tmp)));
|
||||
if(fi.exists()) {
|
||||
if(fi.isDir()) {
|
||||
QString profile = tmp;
|
||||
@@ -184,13 +184,13 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
bool in_root = true;
|
||||
QString name = qmake_getpwd();
|
||||
if(project->isActiveConfig("flat")) {
|
||||
QString flat_file = fileFixify(name, oldpwd, oldoutpwd, FileFixifyRelative);
|
||||
QString flat_file = fileFixify(name, FileFixifyBackwards | FileFixifyRelative);
|
||||
if(flat_file.indexOf(Option::dir_sep) != -1) {
|
||||
QStringList dirs = flat_file.split(Option::dir_sep);
|
||||
name = dirs.back();
|
||||
}
|
||||
} else {
|
||||
QString flat_file = fileFixify(name, oldpwd, oldoutpwd, FileFixifyRelative);
|
||||
QString flat_file = fileFixify(name, FileFixifyBackwards | FileFixifyRelative);
|
||||
if(QDir::isRelativePath(flat_file) && flat_file.indexOf(Option::dir_sep) != -1) {
|
||||
QString last_grp("QMAKE_SUBDIR_PBX_HEIR_GROUP");
|
||||
QStringList dirs = flat_file.split(Option::dir_sep);
|
||||
@@ -215,7 +215,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
t << "\t\t" << project_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("lastKnownFileType", "wrapper.pb-project") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(tmp_proj.first("TARGET") + projectSuffix())) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", tmp_proj.first("TARGET") + projectSuffix()) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("path", pbxproj) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
@@ -283,7 +283,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
t << "\t\t" << keyFor(grp_it.key()) << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", grp_it.key().section(Option::dir_sep, -1)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
@@ -307,7 +307,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
ProString name = l.at(i);
|
||||
const ProKey buildKey(name + ".build");
|
||||
if (!project->isEmpty(buildKey)) {
|
||||
const QString build = project->values(buildKey).first().toQString();
|
||||
const QString build = project->first(buildKey).toQString();
|
||||
if (build.toLower() != configName.toLower())
|
||||
continue;
|
||||
}
|
||||
@@ -344,7 +344,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_AGGREGATE_TARGET") << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildPhases", ProStringList(), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\tbuildSettings = {\n"
|
||||
<< "\t\t\t\t" << writeSettings("PRODUCT_NAME", project->values("TARGET").first()) << ";\n"
|
||||
<< "\t\t\t\t" << writeSettings("PRODUCT_NAME", project->first("TARGET")) << ";\n"
|
||||
<< "\t\t\t};\n";
|
||||
{
|
||||
ProStringList dependencies;
|
||||
@@ -354,8 +354,8 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
|
||||
t << "\t\t\t" << writeSettings("dependencies", dependencies, SettingsAsList, 4) << ";\n"
|
||||
}
|
||||
t << "\t\t\t" << writeSettings("isa", "PBXAggregateTarget", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", project->values("TARGET").first()) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productName", project->values("TARGET").first()) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", project->first("TARGET")) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productName", project->first("TARGET")) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
#endif
|
||||
|
||||
@@ -455,8 +455,8 @@ ProjectBuilderSources::files(QMakeProject *project) const
|
||||
{
|
||||
QStringList ret = project->values(ProKey(key)).toQStringList();
|
||||
if(key == "QMAKE_INTERNAL_INCLUDED_FILES") {
|
||||
QString qtPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectivePaths) + '/');
|
||||
QString qtSrcPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectiveSourcePaths) + '/');
|
||||
QString qtPrefix(project->propertyValue(ProKey("QT_INSTALL_PREFIX/get")).toQString() + '/');
|
||||
QString qtSrcPrefix(project->propertyValue(ProKey("QT_INSTALL_PREFIX/src")).toQString() + '/');
|
||||
|
||||
QStringList newret;
|
||||
for(int i = 0; i < ret.size(); ++i) {
|
||||
@@ -507,14 +507,6 @@ static QString xcodeFiletypeForFilename(const QString &filename)
|
||||
bool
|
||||
ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
{
|
||||
// The code in this function assumes that the current directory matches
|
||||
// the output directory, which is not actually the case when we are called
|
||||
// from the generic generator code. Instead of changing every single
|
||||
// assumption and fileFixify we cheat by moving into the output directory
|
||||
// for the duration of this function.
|
||||
QString input_dir = qmake_getpwd();
|
||||
qmake_setpwd(Option::output_dir);
|
||||
|
||||
ProStringList tmp;
|
||||
bool did_preprocess = false;
|
||||
|
||||
@@ -536,7 +528,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
QFile mkf(mkfile);
|
||||
if(mkf.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
writingUnixMakefileGenerator = true;
|
||||
qmake_setpwd(input_dir); // Makefile generation assumes input_dir as pwd
|
||||
debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData());
|
||||
QTextStream mkt(&mkf);
|
||||
writeHeader(mkt);
|
||||
@@ -545,10 +536,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
mkt.flush();
|
||||
mkf.close();
|
||||
writingUnixMakefileGenerator = false;
|
||||
qmake_setpwd(Option::output_dir);
|
||||
}
|
||||
QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE");
|
||||
mkfile = fileFixify(mkfile, qmake_getpwd());
|
||||
mkfile = fileFixify(mkfile);
|
||||
project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
|
||||
t << "\t\t" << phase_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
|
||||
@@ -557,16 +547,20 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Qmake") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(Option::output_dir)
|
||||
+ " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
// FIXME: Move all file resolving logic out of ProjectBuilderSources::files(), as it
|
||||
// doesn't have access to any of the information it needs to resolve relative paths.
|
||||
project->values("QMAKE_INTERNAL_INCLUDED_FILES").prepend(fileFixify(project->projectFile(), qmake_getpwd(), input_dir));
|
||||
project->values("QMAKE_INTERNAL_INCLUDED_FILES").prepend(project->projectFile());
|
||||
|
||||
// Since we can't fileFixify inside ProjectBuilderSources::files(), we resolve the absolute paths here
|
||||
project->values("QMAKE_INTERNAL_INCLUDED_FILES") = ProStringList(fileFixify(project->values("QMAKE_INTERNAL_INCLUDED_FILES").toQStringList(), FileFixifyAbsolute));
|
||||
project->values("QMAKE_INTERNAL_INCLUDED_FILES") = ProStringList(
|
||||
fileFixify(project->values("QMAKE_INTERNAL_INCLUDED_FILES").toQStringList(),
|
||||
FileFixifyFromOutdir | FileFixifyAbsolute));
|
||||
|
||||
//DUMP SOURCES
|
||||
QMap<QString, ProStringList> groups;
|
||||
@@ -623,11 +617,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
ProStringList &src_list = project->values(ProKey("QMAKE_PBX_" + sources.at(source).keyName()));
|
||||
ProStringList &root_group_list = project->values("QMAKE_PBX_GROUPS");
|
||||
|
||||
const QStringList &files = fileFixify(sources.at(source).files(project));
|
||||
const QStringList &files = fileFixify(sources.at(source).files(project),
|
||||
FileFixifyFromOutdir | FileFixifyAbsolute);
|
||||
for(int f = 0; f < files.count(); ++f) {
|
||||
QString file = files[f];
|
||||
if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0])
|
||||
file = file.mid(1, file.length()-2);
|
||||
if(!sources.at(source).compilerName().isNull() &&
|
||||
!verifyExtraCompiler(sources.at(source).compilerName(), file))
|
||||
continue;
|
||||
@@ -637,12 +630,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
bool in_root = true;
|
||||
QString src_key = keyFor(file);
|
||||
|
||||
file = fileFixify(file, qmake_getpwd(), Option::output_dir, FileFixifyAbsolute);
|
||||
QString name = file.split(Option::dir_sep).back();
|
||||
|
||||
if (!project->isActiveConfig("flat")) {
|
||||
// Build group hierarchy for file references that match the source our build dir
|
||||
QString relativePath = fileFixify(file, input_dir, qmake_getpwd(), FileFixifyRelative);
|
||||
QString relativePath = fileFixify(file, FileFixifyToIndir | FileFixifyRelative);
|
||||
if (QDir::isRelativePath(relativePath) && relativePath.startsWith(QLatin1String("../")))
|
||||
relativePath = fileFixify(file, FileFixifyRelative); // Try build dir
|
||||
|
||||
@@ -678,9 +670,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
//source reference
|
||||
t << "\t\t" << src_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("path", escapeFilePath(file)) << ";\n";
|
||||
<< "\t\t\t" << writeSettings("path", file) << ";\n";
|
||||
if (name != file)
|
||||
t << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";\n";
|
||||
t << "\t\t\t" << writeSettings("name", name) << ";\n";
|
||||
t << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n";
|
||||
QString filetype = xcodeFiletypeForFilename(file);
|
||||
if (!filetype.isNull())
|
||||
@@ -715,7 +707,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << "\t\t" << keyFor(grp_it.key()) << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", grp_it.key().section(Option::dir_sep, -1)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
@@ -730,8 +722,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData());
|
||||
QTextStream mkt(&mkf);
|
||||
writeHeader(mkt);
|
||||
mkt << "MOC = " << Option::fixPathToTargetOS(var("QMAKE_MOC")) << endl;
|
||||
mkt << "UIC = " << Option::fixPathToTargetOS(var("QMAKE_UIC")) << endl;
|
||||
mkt << "MOC = " << var("QMAKE_MOC") << endl;
|
||||
mkt << "UIC = " << var("QMAKE_UIC") << endl;
|
||||
mkt << "LEX = " << var("QMAKE_LEX") << endl;
|
||||
mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
|
||||
mkt << "YACC = " << var("QMAKE_YACC") << endl;
|
||||
@@ -739,13 +731,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
mkt << "DEFINES = "
|
||||
<< varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ")
|
||||
<< varGlue("DEFINES","-D"," -D","") << endl;
|
||||
mkt << "INCPATH = -I" << specdir();
|
||||
if(!project->isActiveConfig("no_include_pwd")) {
|
||||
QString pwd = escapeFilePath(fileFixify(qmake_getpwd()));
|
||||
if(pwd.isEmpty())
|
||||
pwd = ".";
|
||||
mkt << " -I" << pwd;
|
||||
}
|
||||
mkt << "INCPATH =";
|
||||
{
|
||||
const ProStringList &incs = project->values("INCLUDEPATH");
|
||||
for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit)
|
||||
@@ -756,30 +742,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
mkt << endl;
|
||||
mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
|
||||
mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl;
|
||||
mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl;
|
||||
mkt << "PARSERS =";
|
||||
if(!project->isEmpty("YACCSOURCES")) {
|
||||
const ProStringList &yaccs = project->values("YACCSOURCES");
|
||||
for (ProStringList::ConstIterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) {
|
||||
QFileInfo fi(fileInfo((*yit).toQString()));
|
||||
mkt << " " << fi.path() << Option::dir_sep << fi.baseName()
|
||||
<< Option::yacc_mod << Option::cpp_ext.first();
|
||||
}
|
||||
}
|
||||
if(!project->isEmpty("LEXSOURCES")) {
|
||||
const ProStringList &lexs = project->values("LEXSOURCES");
|
||||
for (ProStringList::ConstIterator lit = lexs.begin(); lit != lexs.end(); ++lit) {
|
||||
QFileInfo fi(fileInfo((*lit).toQString()));
|
||||
mkt << " " << fi.path() << Option::dir_sep << fi.baseName()
|
||||
<< Option::lex_mod << Option::cpp_ext.first();
|
||||
}
|
||||
}
|
||||
mkt << "\n";
|
||||
mkt << "preprocess: $(PARSERS) compilers\n";
|
||||
mkt << "clean preprocess_clean: parser_clean compiler_clean\n\n";
|
||||
mkt << "parser_clean:\n";
|
||||
if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES"))
|
||||
mkt << "\t-rm -f $(PARSERS)\n";
|
||||
mkt << "preprocess: compilers\n";
|
||||
mkt << "clean preprocess_clean: compiler_clean\n\n";
|
||||
writeExtraTargets(mkt);
|
||||
if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) {
|
||||
mkt << "compilers:";
|
||||
@@ -800,8 +764,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if(added && !(added % 3))
|
||||
mkt << "\\\n\t";
|
||||
++added;
|
||||
const QString file_name = fileFixify(fn, Option::output_dir, Option::output_dir);
|
||||
mkt << " " << replaceExtraCompilerVariables(Option::fixPathToTargetOS(tmp_out.first().toQString(), false), file_name, QString());
|
||||
const QString file_name = fileFixify(fn, FileFixifyFromOutdir);
|
||||
mkt << ' ' << escapeDependencyPath(Option::fixPathToTargetOS(
|
||||
replaceExtraCompilerVariables(tmp_out.first().toQString(), file_name, QString(), NoShell)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -812,7 +777,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
mkt.flush();
|
||||
mkf.close();
|
||||
}
|
||||
mkfile = fileFixify(mkfile, qmake_getpwd());
|
||||
mkfile = fileFixify(mkfile);
|
||||
QString phase_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET");
|
||||
// project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
|
||||
project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
|
||||
@@ -823,7 +788,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(Option::output_dir)
|
||||
+ " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
@@ -843,22 +810,17 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
|
||||
ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"),
|
||||
&frameworkdirs = project->values("QMAKE_FRAMEWORKPATH");
|
||||
static const char * const libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
|
||||
static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
|
||||
for (int i = 0; libs[i]; i++) {
|
||||
tmp = project->values(libs[i]);
|
||||
for(int x = 0; x < tmp.count();) {
|
||||
bool remove = false;
|
||||
QString library, name;
|
||||
ProString opt = tmp[x].trimmed();
|
||||
if (opt.length() >= 2 && (opt.at(0) == '"' || opt.at(0) == '\'') && opt.endsWith(opt.at(0)))
|
||||
opt = opt.mid(1, opt.length()-2);
|
||||
if(opt.startsWith("-L")) {
|
||||
QString r = opt.mid(2).toQString();
|
||||
fixForOutput(r);
|
||||
libdirs.append(r);
|
||||
} else if(opt == "-prebind") {
|
||||
project->values("QMAKE_DO_PREBINDING").append("TRUE");
|
||||
remove = true;
|
||||
} else if(opt.startsWith("-l")) {
|
||||
name = opt.mid(2).toQString();
|
||||
QString lib("lib" + name);
|
||||
@@ -887,10 +849,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString();
|
||||
suffixSetting = "$(" + suffixSetting + ")";
|
||||
if (!librarySuffix.isEmpty()) {
|
||||
library = library.replace(librarySuffix, suffixSetting);
|
||||
name = name.remove(librarySuffix);
|
||||
library.replace(librarySuffix, suffixSetting);
|
||||
name.remove(librarySuffix);
|
||||
} else {
|
||||
library = library.replace(name, name + suffixSetting);
|
||||
library.replace(name, name + suffixSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -956,15 +918,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if(!path.isEmpty() && !libdirs.contains(path))
|
||||
libdirs += path;
|
||||
}
|
||||
library = fileFixify(library);
|
||||
QString filetype = xcodeFiletypeForFilename(library);
|
||||
library = fileFixify(library, FileFixifyFromOutdir | FileFixifyAbsolute);
|
||||
QString key = keyFor(library);
|
||||
if (!project->values("QMAKE_PBX_LIBRARIES").contains(key)) {
|
||||
bool is_frmwrk = (library.endsWith(".framework"));
|
||||
t << "\t\t" << key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("path", escapeFilePath(library)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", name) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("path", library) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(library)), SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n";
|
||||
if (is_frmwrk)
|
||||
@@ -999,21 +960,22 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
QTextStream mkt(&mkf);
|
||||
writeHeader(mkt);
|
||||
mkt << "SUBLIBS= ";
|
||||
// ### This is missing the parametrization found in unixmake2.cpp
|
||||
tmp = project->values("SUBLIBS");
|
||||
for(int i = 0; i < tmp.count(); i++)
|
||||
t << "tmp/lib" << tmp[i] << ".a ";
|
||||
t << escapeFilePath("tmp/lib" + tmp[i] + ".a") << ' ';
|
||||
t << endl << endl;
|
||||
mkt << "sublibs: $(SUBLIBS)\n\n";
|
||||
tmp = project->values("SUBLIBS");
|
||||
for(int i = 0; i < tmp.count(); i++)
|
||||
t << "tmp/lib" << tmp[i] << ".a:\n\t"
|
||||
t << escapeFilePath("tmp/lib" + tmp[i] + ".a") + ":\n\t"
|
||||
<< var(ProKey("MAKELIB" + tmp[i])) << endl << endl;
|
||||
mkt.flush();
|
||||
mkf.close();
|
||||
writingUnixMakefileGenerator = false;
|
||||
}
|
||||
QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE");
|
||||
mkfile = fileFixify(mkfile, qmake_getpwd());
|
||||
mkfile = fileFixify(mkfile);
|
||||
project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
|
||||
t << "\t\t" << phase_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
|
||||
@@ -1022,7 +984,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Sublibs") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << "\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(Option::output_dir)
|
||||
+ " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
@@ -1058,6 +1022,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_PRE_LINK")) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
@@ -1070,7 +1035,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << "\t\t" << key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_LIBRARIES"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", grp) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
@@ -1083,7 +1048,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("files", project->values("QMAKE_PBX_BUILD_LIBRARIES"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXFrameworksBuildPhase", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", grp) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
@@ -1101,14 +1066,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
if (!project->isEmpty("DESTDIR")) {
|
||||
QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE");
|
||||
QString destDir = project->first("DESTDIR").toQString();
|
||||
destDir = fixForOutput(destDir);
|
||||
destDir = fileInfo(Option::fixPathToLocalOS(destDir)).absoluteFilePath();
|
||||
QString destDir = fileFixify(project->first("DESTDIR").toQString(),
|
||||
FileFixifyFromOutdir | FileFixifyAbsolute);
|
||||
project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
|
||||
t << "\t\t" << phase_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
|
||||
@@ -1119,7 +1084,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("outputPaths", ProStringList(), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + escapeFilePath(destDir))) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + IoUtils::shellQuoteUnix(destDir))) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app";
|
||||
@@ -1137,13 +1103,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
//all files
|
||||
const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files"));
|
||||
for(int file = 0; file < files.count(); file++) {
|
||||
QString fn = fileFixify(files[file].toQString(), Option::output_dir, input_dir, FileFixifyAbsolute);
|
||||
QString fn = fileFixify(files[file].toQString(), FileFixifyAbsolute);
|
||||
QString name = fn.split(Option::dir_sep).back();
|
||||
QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE_REF." + bundle_data[i] + "-" + fn);
|
||||
bundle_file_refs += file_ref_key;
|
||||
t << "\t\t" << file_ref_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("path", escapeFilePath(fn)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("path", fn) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", name) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
@@ -1169,7 +1135,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << "\t\t" << phase_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Copy '" + bundle_data[i] + "' Files to Bundle") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("dstPath", path) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("files", bundle_files, SettingsAsList, 4) << ";\n"
|
||||
@@ -1193,8 +1159,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if (copyBundleResources) {
|
||||
if (!project->isEmpty("ICON")) {
|
||||
ProString icon = project->first("ICON");
|
||||
if (icon.length() >= 2 && (icon.at(0) == '"' || icon.at(0) == '\'') && icon.endsWith(icon.at(0)))
|
||||
icon = icon.mid(1, icon.length() - 2);
|
||||
bundle_resources_files += keyFor(icon + ".BUILDABLE");
|
||||
}
|
||||
|
||||
@@ -1207,7 +1171,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "\t\t\t" << writeSettings("files", bundle_resources_files, SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXResourcesBuildPhase", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", grp) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
}
|
||||
|
||||
@@ -1232,9 +1196,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
} else {
|
||||
t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.executable") << ";\n";
|
||||
}
|
||||
QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") :
|
||||
qmake_getpwd()) + Option::dir_sep + targ;
|
||||
t << "\t\t\t" << writeSettings("path", escapeFilePath(targ)) << ";\n";
|
||||
t << "\t\t\t" << writeSettings("path", targ) << ";\n";
|
||||
} else {
|
||||
ProString lib = project->first("QMAKE_ORIG_TARGET");
|
||||
if(project->isActiveConfig("staticlib")) {
|
||||
@@ -1262,7 +1224,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
} else {
|
||||
t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.dylib") << ";\n";
|
||||
}
|
||||
t << "\t\t\t" << writeSettings("path", escapeFilePath(lib)) << ";\n";
|
||||
t << "\t\t\t" << writeSettings("path", lib) << ";\n";
|
||||
}
|
||||
t << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
@@ -1282,7 +1244,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_GROUPS"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", project->first("QMAKE_ORIG_TARGET")) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
@@ -1328,14 +1290,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
else
|
||||
t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";\n";
|
||||
}
|
||||
t << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productName", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n";
|
||||
t << "\t\t\t" << writeSettings("name", project->first("QMAKE_ORIG_TARGET")) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productName", project->first("QMAKE_ORIG_TARGET")) << ";\n";
|
||||
} else {
|
||||
ProString lib = project->first("QMAKE_ORIG_TARGET");
|
||||
if(!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
|
||||
lib.prepend("lib");
|
||||
t << "\t\t\t" << writeSettings("name", escapeFilePath(lib)) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productName", escapeFilePath(lib)) << ";\n";
|
||||
t << "\t\t\t" << writeSettings("name", lib) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productName", lib) << ";\n";
|
||||
if (!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE"))
|
||||
t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";\n";
|
||||
else if (project->isActiveConfig("staticlib"))
|
||||
@@ -1346,8 +1308,98 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.library.dynamic") << ";\n";
|
||||
}
|
||||
if(!project->isEmpty("DESTDIR"))
|
||||
t << "\t\t\t" << writeSettings("productInstallPath", escapeFilePath(project->first("DESTDIR"))) << ";\n";
|
||||
t << "\t\t\t" << writeSettings("productInstallPath", project->first("DESTDIR")) << ";\n";
|
||||
t << "\t\t};\n";
|
||||
|
||||
// Test target for running Qt unit tests under XCTest
|
||||
if (project->isActiveConfig("testcase") && project->isActiveConfig("app_bundle")) {
|
||||
QString devNullFileReferenceKey = keyFor(pbx_dir + "QMAKE_PBX_DEV_NULL_FILE_REFERENCE");
|
||||
t << "\t\t" << devNullFileReferenceKey << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "/dev/null") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("path", "/dev/null") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("lastKnownFileType", "sourcecode.c.c") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
QString devNullBuildFileKey = keyFor(pbx_dir + "QMAKE_PBX_DEV_NULL_BUILD_FILE");
|
||||
t << "\t\t" << devNullBuildFileKey << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("fileRef", devNullFileReferenceKey) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
QString dummySourceBuildPhaseKey = keyFor(pbx_dir + "QMAKE_PBX_DUMMY_SOURCE_BUILD_PHASE");
|
||||
t << "\t\t" << dummySourceBuildPhaseKey << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("files", devNullBuildFileKey, SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXSourcesBuildPhase", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
ProStringList testBundleBuildConfigs;
|
||||
|
||||
ProString targetName = project->first("QMAKE_ORIG_TARGET");
|
||||
ProString testHost = "$(BUILT_PRODUCTS_DIR)/" + targetName + ".app/";
|
||||
if (!project->isActiveConfig("ios"))
|
||||
testHost.append("Contents/MacOS/");
|
||||
testHost.append(targetName);
|
||||
|
||||
static const char * const configs[] = { "Debug", "Release", 0 };
|
||||
for (int i = 0; configs[i]; i++) {
|
||||
QString testBundleBuildConfig = keyFor(pbx_dir + "QMAKE_PBX_TEST_BUNDLE_BUILDCONFIG_" + configs[i]);
|
||||
t << "\t\t" << testBundleBuildConfig << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\tbuildSettings = {\n"
|
||||
<< "\t\t\t\t" << writeSettings("INFOPLIST_FILE", project->first("QMAKE_XCODE_SPECDIR") + "/QtTest.plist") << ";\n"
|
||||
<< "\t\t\t\t" << writeSettings("OTHER_LDFLAGS", "") << ";\n"
|
||||
<< "\t\t\t\t" << writeSettings("TEST_HOST", testHost) << ";\n"
|
||||
<< "\t\t\t\t" << writeSettings("DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym") << ";\n"
|
||||
<< "\t\t\t};\n"
|
||||
<< "\t\t\t" << writeSettings("name", configs[i], SettingsNoQuote) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
testBundleBuildConfigs.append(testBundleBuildConfig);
|
||||
}
|
||||
|
||||
QString testBundleBuildConfigurationListKey = keyFor(pbx_dir + "QMAKE_PBX_TEST_BUNDLE_BUILDCONFIG_LIST");
|
||||
t << "\t\t" << testBundleBuildConfigurationListKey << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("buildConfigurations", testBundleBuildConfigs, SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("defaultConfigurationName", "Debug", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
QString primaryTargetDependencyKey = keyFor(pbx_dir + "QMAKE_PBX_PRIMARY_TARGET_DEP");
|
||||
t << "\t\t" << primaryTargetDependencyKey << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXTargetDependency", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("target", keyFor(pbx_dir + "QMAKE_PBX_TARGET")) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
QString testBundleReferenceKey = keyFor("QMAKE_TEST_BUNDLE_REFERENCE");
|
||||
t << "\t\t" << testBundleReferenceKey << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("explicitFileType", "wrapper.cfbundle") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("includeInIndex", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
QString testTargetKey = keyFor(pbx_dir + "QMAKE_PBX_TEST_TARGET");
|
||||
project->values("QMAKE_PBX_TARGETS").append(testTargetKey);
|
||||
t << "\t\t" << testTargetKey << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildPhases", dummySourceBuildPhaseKey, SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("dependencies", primaryTargetDependencyKey, SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("buildConfigurationList", testBundleBuildConfigurationListKey) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productType", "com.apple.product-type.bundle.unit-test") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("productReference", testBundleReferenceKey) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Test") << ";\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
QLatin1Literal testTargetID("TestTargetID");
|
||||
project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + testTargetKey + "_" + testTargetID)).append(keyFor(pbx_dir + "QMAKE_PBX_TARGET"));
|
||||
project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + testTargetKey)).append(ProKey(testTargetID));
|
||||
}
|
||||
|
||||
//DEBUG/RELEASE
|
||||
QString defaultConfig;
|
||||
for(int as_release = 0; as_release < 2; as_release++)
|
||||
@@ -1356,6 +1408,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
|
||||
QMap<QString, QString> settings;
|
||||
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
|
||||
// Bitcode is only supported with a deployment target >= iOS 6.0.
|
||||
// Disable it for now, and consider switching it on when later
|
||||
// bumping the deployment target.
|
||||
settings.insert("ENABLE_BITCODE", "NO");
|
||||
settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES");
|
||||
if(!as_release)
|
||||
settings.insert("GCC_OPTIMIZATION_LEVEL", "0");
|
||||
@@ -1367,14 +1423,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
ProString name = l.at(i);
|
||||
const ProKey buildKey(name + ".build");
|
||||
if (!project->isEmpty(buildKey)) {
|
||||
const QString build = project->values(buildKey).first().toQString();
|
||||
const QString build = project->first(buildKey).toQString();
|
||||
if (build.toLower() != configName.toLower())
|
||||
continue;
|
||||
}
|
||||
const QString value = project->values(ProKey(name + ".value")).join(QString(Option::field_sep));
|
||||
const ProKey nkey(name + ".name");
|
||||
if (!project->isEmpty(nkey))
|
||||
name = project->values(nkey).first();
|
||||
name = project->first(nkey);
|
||||
settings.insert(name.toQString(), value);
|
||||
}
|
||||
}
|
||||
@@ -1384,7 +1440,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
ProString lib = project->first("QMAKE_ORIG_TARGET");
|
||||
if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
|
||||
lib.prepend("lib");
|
||||
settings.insert("PRODUCT_NAME", escapeFilePath(lib.toQString()));
|
||||
settings.insert("PRODUCT_NAME", lib.toQString());
|
||||
}
|
||||
|
||||
if (project->isActiveConfig("debug") != (bool)as_release)
|
||||
@@ -1415,10 +1471,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if ((project->first("TEMPLATE") == "app" && project->isActiveConfig("app_bundle")) ||
|
||||
(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") &&
|
||||
project->isActiveConfig("lib_bundle"))) {
|
||||
QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString(), Option::output_dir, input_dir);
|
||||
QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString(), FileFixifyToIndir);
|
||||
if (!plist.isEmpty()) {
|
||||
if (exists(plist))
|
||||
t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", plist) << ";\n";
|
||||
t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", fileFixify(plist)) << ";\n";
|
||||
else
|
||||
warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.", plist.toLatin1().constData());
|
||||
} else {
|
||||
@@ -1427,30 +1483,29 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if (plist_in_file.open(QIODevice::ReadOnly)) {
|
||||
QTextStream plist_in(&plist_in_file);
|
||||
QString plist_in_text = plist_in.readAll();
|
||||
plist_in_text = plist_in_text.replace("@ICON@",
|
||||
plist_in_text.replace("@ICON@",
|
||||
(project->isEmpty("ICON") ? QString("") : project->first("ICON").toQString().section(Option::dir_sep, -1)));
|
||||
if (project->first("TEMPLATE") == "app") {
|
||||
plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString());
|
||||
plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString());
|
||||
} else {
|
||||
plist_in_text = plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString());
|
||||
plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString());
|
||||
}
|
||||
QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
|
||||
if (bundlePrefix.isEmpty())
|
||||
bundlePrefix = "com.yourcompany";
|
||||
plist_in_text = plist_in_text.replace("@BUNDLEIDENTIFIER@", bundlePrefix + "." + QLatin1String("${PRODUCT_NAME:rfc1034identifier}"));
|
||||
plist_in_text.replace("@BUNDLEIDENTIFIER@", bundlePrefix + '.' + QLatin1String("${PRODUCT_NAME:rfc1034identifier}"));
|
||||
if (!project->values("VERSION").isEmpty()) {
|
||||
plist_in_text = plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." +
|
||||
project->first("VER_MIN"));
|
||||
plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + project->first("VER_MIN"));
|
||||
}
|
||||
plist_in_text = plist_in_text.replace("@TYPEINFO@",
|
||||
plist_in_text.replace("@TYPEINFO@",
|
||||
(project->isEmpty("QMAKE_PKGINFO_TYPEINFO")
|
||||
? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString()));
|
||||
QString plist_dir;
|
||||
if (!project->isEmpty("PLIST_DIR"))
|
||||
plist_dir = project->first("PLIST_DIR").toQString();
|
||||
QString plist_in_filename = QFileInfo(plist_in_file).fileName();
|
||||
QFile plist_out_file(plist_dir + plist_in_filename);
|
||||
if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QFile plist_out_file(Option::output_dir + "/" + plist_dir + plist_in_filename);
|
||||
if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream plist_out(&plist_out_file);
|
||||
plist_out << plist_in_text;
|
||||
t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", fixForOutput(plist_dir + plist_in_filename)) << ";\n";
|
||||
@@ -1459,12 +1514,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
}
|
||||
}
|
||||
|
||||
t << "\t\t\t\t" << writeSettings("SYMROOT", escapeFilePath(qmake_getpwd())) << ";\n";
|
||||
t << "\t\t\t\t" << writeSettings("SYMROOT", Option::output_dir) << ";\n";
|
||||
|
||||
if (!project->isEmpty("DESTDIR")) {
|
||||
ProString dir = project->first("DESTDIR");
|
||||
if (QDir::isRelativePath(dir.toQString()))
|
||||
dir.prepend(qmake_getpwd() + Option::dir_sep);
|
||||
dir.prepend(Option::output_dir + Option::dir_sep);
|
||||
t << "\t\t\t\t" << writeSettings("INSTALL_DIR", dir) << ";\n";
|
||||
}
|
||||
|
||||
@@ -1495,13 +1550,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
QString var = tmp[i].toQString(), val = QString::fromLocal8Bit(qgetenv(var.toLatin1().constData()));
|
||||
if (val.isEmpty() && var == "TB")
|
||||
val = "/usr/bin/";
|
||||
t << "\t\t\t\t" << writeSettings(var, escapeFilePath(val)) << ";\n";
|
||||
t << "\t\t\t\t" << writeSettings(var, val) << ";\n";
|
||||
}
|
||||
if (!project->isEmpty("PRECOMPILED_HEADER")) {
|
||||
t << "\t\t\t\t" << writeSettings("GCC_PRECOMPILE_PREFIX_HEADER", "YES") << ";\n"
|
||||
<< "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", escapeFilePath(project->first("PRECOMPILED_HEADER"))) << ";\n";
|
||||
<< "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", project->first("PRECOMPILED_HEADER")) << ";\n";
|
||||
}
|
||||
t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + ProStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";\n"
|
||||
t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH"), SettingsAsList, 5) << ";\n"
|
||||
<< "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";\n"
|
||||
<< "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"),
|
||||
!project->values("QMAKE_FRAMEWORKPATH").isEmpty() ? SettingsAsList : 0, 5) << ";\n";
|
||||
@@ -1530,8 +1585,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS",
|
||||
fixListForOutput("SUBLIBS")
|
||||
+ fixListForOutput("QMAKE_LFLAGS")
|
||||
+ fixListForOutput("QMAKE_LIBS")
|
||||
+ fixListForOutput("QMAKE_LIBS_PRIVATE"),
|
||||
+ fixListForOutput(fixLibFlags("QMAKE_LIBS"))
|
||||
+ fixListForOutput(fixLibFlags("QMAKE_LIBS_PRIVATE")),
|
||||
SettingsAsList, 6) << ";\n";
|
||||
}
|
||||
const ProStringList &archs = !project->values("QMAKE_XCODE_ARCHS").isEmpty() ?
|
||||
@@ -1539,7 +1594,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if (!archs.isEmpty())
|
||||
t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";\n";
|
||||
if (!project->isEmpty("OBJECTS_DIR"))
|
||||
t << "\t\t\t\t" << writeSettings("OBJROOT", escapeFilePath(project->first("OBJECTS_DIR").toQString())) << ";\n";
|
||||
t << "\t\t\t\t" << writeSettings("OBJROOT", project->first("OBJECTS_DIR")) << ";\n";
|
||||
} else {
|
||||
if (project->first("TEMPLATE") == "app") {
|
||||
t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET").toQString())) << ";\n";
|
||||
@@ -1551,7 +1606,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
ProString lib = project->first("QMAKE_ORIG_TARGET");
|
||||
if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
|
||||
lib.prepend("lib");
|
||||
t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", escapeFilePath(lib)) << ";\n";
|
||||
t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", lib) << ";\n";
|
||||
}
|
||||
}
|
||||
t << "\t\t\t};\n"
|
||||
@@ -1578,6 +1633,19 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << "\t\t\t" << writeSettings("projectDirPath", ProStringList()) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("projectRoot", "") << ";\n"
|
||||
<< "\t\t\t" << writeSettings("targets", project->values("QMAKE_PBX_TARGETS"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << "attributes = {\n"
|
||||
<< "\t\t\t\tTargetAttributes = {\n";
|
||||
foreach (const ProString &target, project->values("QMAKE_PBX_TARGETS")) {
|
||||
const ProStringList &attributes = project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + target));
|
||||
if (attributes.isEmpty())
|
||||
continue;
|
||||
t << "\t\t\t\t\t" << target << " = {\n";
|
||||
foreach (const ProString &attribute, attributes)
|
||||
t << "\t\t\t\t\t\t" << writeSettings(attribute.toQString(), project->first(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + target + "_" + attribute))) << ";\n";
|
||||
t << "\t\t\t\t\t};\n";
|
||||
}
|
||||
t << "\t\t\t\t};\n"
|
||||
<< "\t\t\t};\n"
|
||||
<< "\t\t};\n";
|
||||
|
||||
// FIXME: Deal with developmentRegion and knownRegions for QMAKE_PBX_ROOT
|
||||
@@ -1588,8 +1656,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
<< "}\n";
|
||||
|
||||
if(project->isActiveConfig("generate_pbxbuild_makefile")) {
|
||||
QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
|
||||
qmake_getpwd());
|
||||
QString mkwrap = Option::output_dir + project->first("/MAKEFILE");
|
||||
QFile mkwrapf(mkwrap);
|
||||
if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
writingUnixMakefileGenerator = true;
|
||||
@@ -1597,13 +1664,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
QTextStream mkwrapt(&mkwrapf);
|
||||
writeHeader(mkwrapt);
|
||||
const char cleans[] = "preprocess_clean ";
|
||||
const QString cmd = escapeFilePath(project->first("QMAKE_ORIG_TARGET") + projectSuffix() + "/") + " && " + pbxbuild();
|
||||
mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n"
|
||||
<< "all:\n\t"
|
||||
<< "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n"
|
||||
<< "cd " << cmd << "\n"
|
||||
<< "install: all\n\t"
|
||||
<< "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n"
|
||||
<< "cd " << cmd << " install\n"
|
||||
<< "distclean clean: preprocess_clean\n\t"
|
||||
<< "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " clean\n"
|
||||
<< "cd " << cmd << " clean\n"
|
||||
<< (!did_preprocess ? cleans : "") << ":\n";
|
||||
if(did_preprocess)
|
||||
mkwrapt << cleans << ":\n\t"
|
||||
@@ -1613,7 +1681,52 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
}
|
||||
}
|
||||
|
||||
qmake_setpwd(input_dir);
|
||||
// Scheme
|
||||
{
|
||||
QString xcodeSpecDir = project->first("QMAKE_XCODE_SPECDIR").toQString();
|
||||
|
||||
bool wroteCustomScheme = false;
|
||||
|
||||
QString projectSharedSchemesPath = pbx_dir + "/xcshareddata/xcschemes";
|
||||
if (mkdir(projectSharedSchemesPath)) {
|
||||
QString target = project->first("QMAKE_ORIG_TARGET").toQString();
|
||||
|
||||
QFile defaultSchemeFile(xcodeSpecDir + "/default.xcscheme");
|
||||
QFile outputSchemeFile(projectSharedSchemesPath + Option::dir_sep + target + ".xcscheme");
|
||||
|
||||
if (defaultSchemeFile.open(QIODevice::ReadOnly)
|
||||
&& outputSchemeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
|
||||
QTextStream defaultSchemeStream(&defaultSchemeFile);
|
||||
QString schemeData = defaultSchemeStream.readAll();
|
||||
|
||||
schemeData.replace("@QMAKE_ORIG_TARGET@", target);
|
||||
schemeData.replace("@TARGET_PBX_KEY@", keyFor(pbx_dir + "QMAKE_PBX_TARGET"));
|
||||
schemeData.replace("@TEST_BUNDLE_PBX_KEY@", keyFor("QMAKE_TEST_BUNDLE_REFERENCE"));
|
||||
|
||||
QTextStream outputSchemeStream(&outputSchemeFile);
|
||||
outputSchemeStream << schemeData;
|
||||
|
||||
wroteCustomScheme = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wroteCustomScheme) {
|
||||
// Prevent Xcode from auto-generating schemes
|
||||
QString workspaceSettingsFilename("WorkspaceSettings.xcsettings");
|
||||
QString workspaceSharedDataPath = pbx_dir + "/project.xcworkspace/xcshareddata";
|
||||
if (mkdir(workspaceSharedDataPath)) {
|
||||
QFile::copy(xcodeSpecDir + Option::dir_sep + workspaceSettingsFilename,
|
||||
workspaceSharedDataPath + Option::dir_sep + workspaceSettingsFilename);
|
||||
} else {
|
||||
wroteCustomScheme = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wroteCustomScheme)
|
||||
warn_msg(WarnLogic, "Failed to generate schemes in '%s', " \
|
||||
"falling back to Xcode auto-generated schemes", qPrintable(projectSharedSchemesPath));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1703,13 +1816,15 @@ ProjectBuilderMakefileGenerator::openOutput(QFile &file, const QString &build) c
|
||||
output += QDir::separator();
|
||||
}
|
||||
output += QString("project.pbxproj");
|
||||
output = unescapeFilePath(output);
|
||||
file.setFileName(output);
|
||||
bool ret = UnixMakefileGenerator::openOutput(file, build);
|
||||
((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
|
||||
Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
|
||||
return ret;
|
||||
}
|
||||
bool ret = UnixMakefileGenerator::openOutput(file, build);
|
||||
((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
|
||||
Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
|
||||
return ret;
|
||||
|
||||
((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir;
|
||||
return UnixMakefileGenerator::openOutput(file, build);
|
||||
}
|
||||
|
||||
/* This function is such a hack it is almost pointless, but it
|
||||
@@ -1760,8 +1875,6 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const
|
||||
else
|
||||
version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist";
|
||||
#endif
|
||||
} else {
|
||||
version_plist = version_plist.replace(QRegExp("\""), "");
|
||||
}
|
||||
if (ret.isEmpty()) {
|
||||
QFile version_file(version_plist);
|
||||
@@ -1822,7 +1935,7 @@ int
|
||||
ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where)
|
||||
{
|
||||
int ret = 0; //absolute is the default..
|
||||
if(QDir::isRelativePath(unescapeFilePath(where)))
|
||||
if (QDir::isRelativePath(where))
|
||||
ret = 4; //relative
|
||||
return ret;
|
||||
}
|
||||
@@ -1848,26 +1961,6 @@ ProjectBuilderMakefileGenerator::pbxbuild()
|
||||
return (pbuilderVersion() >= 38 ? "xcodebuild" : "pbxbuild");
|
||||
}
|
||||
|
||||
QString
|
||||
ProjectBuilderMakefileGenerator::escapeFilePath(const QString &path) const
|
||||
{
|
||||
#if 1
|
||||
//in the middle of generating a Makefile!
|
||||
if(writingUnixMakefileGenerator)
|
||||
return UnixMakefileGenerator::escapeFilePath(path);
|
||||
|
||||
//generating stuff for the xml file!
|
||||
QString ret = path;
|
||||
if(!ret.isEmpty()) {
|
||||
ret = unescapeFilePath(ret);
|
||||
debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData());
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return UnixMakefileGenerator::escapeFilePath(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
static QString quotedStringLiteral(const QString &value)
|
||||
{
|
||||
QString result;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user