mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Merge branch 'bots' of https://bitbucket.org/johnprestonmail/telegram-desktop into bots
This commit is contained in:
commit
ecce77ec4c
282 changed files with 48983 additions and 24654 deletions
30
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
30
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
|
@ -11,6 +11,7 @@ This document describes how you can contribute to Telegram Desktop. Please read
|
||||||
* [Pull upstream changes into your fork regularly](#pull-upstream-changes-into-your-fork-regularly)
|
* [Pull upstream changes into your fork regularly](#pull-upstream-changes-into-your-fork-regularly)
|
||||||
* [How to get your pull request accepted](#how-to-get-your-pull-request-accepted)
|
* [How to get your pull request accepted](#how-to-get-your-pull-request-accepted)
|
||||||
* [Keep your pull requests limited to a single issue](#keep-your-pull-requests-limited-to-a-single-issue)
|
* [Keep your pull requests limited to a single issue](#keep-your-pull-requests-limited-to-a-single-issue)
|
||||||
|
* [Squash your commits to a single commit](#squash-your-commits-to-a-single-commit)
|
||||||
* [Don't mix code changes with whitespace cleanup](#dont-mix-code-changes-with-whitespace-cleanup)
|
* [Don't mix code changes with whitespace cleanup](#dont-mix-code-changes-with-whitespace-cleanup)
|
||||||
* [Keep your code simple!](#keep-your-code-simple)
|
* [Keep your code simple!](#keep-your-code-simple)
|
||||||
* [Test your changes!](#test-your-changes)
|
* [Test your changes!](#test-your-changes)
|
||||||
|
@ -72,10 +73,8 @@ For more info, see [GitHub Help][help_change_commit_message].
|
||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
|
|
||||||
* [Visual Studio 2013][msvc]
|
See the [README.md](README.md#build-instructions) for details on the various build
|
||||||
* [XCode 6.4][xcode]
|
environments.
|
||||||
* [XCode 6.4 for OS X 10.6 and 10.7][xcode_old]
|
|
||||||
* [Qt Creator 3.2.0 Ubuntu][qtcreator]
|
|
||||||
|
|
||||||
## Pull upstream changes into your fork regularly
|
## Pull upstream changes into your fork regularly
|
||||||
|
|
||||||
|
@ -90,9 +89,13 @@ Check the log to be sure that you actually want the changes, before merging:
|
||||||
|
|
||||||
git log upstream/master
|
git log upstream/master
|
||||||
|
|
||||||
Then merge the changes that you fetched:
|
Then rebase your changes on the latest commits in the `master` branch:
|
||||||
|
|
||||||
git merge upstream/master
|
git rebase upstream/master
|
||||||
|
|
||||||
|
After that, you have to force push your commits:
|
||||||
|
|
||||||
|
git push --force
|
||||||
|
|
||||||
For more info, see [GitHub Help][help_fork_repo].
|
For more info, see [GitHub Help][help_fork_repo].
|
||||||
|
|
||||||
|
@ -107,6 +110,21 @@ Pull requests should be as small/atomic as possible. Large, wide-sweeping change
|
||||||
* If you are making spelling corrections in the docs, don't modify other files.
|
* If you are making spelling corrections in the docs, don't modify other files.
|
||||||
* If you are adding new functions don't '*cleanup*' unrelated functions. That cleanup belongs in another pull request.
|
* If you are adding new functions don't '*cleanup*' unrelated functions. That cleanup belongs in another pull request.
|
||||||
|
|
||||||
|
#### Squash your commits to a single commit
|
||||||
|
|
||||||
|
To keep the history of the project clean, you should make one commit per pull request.
|
||||||
|
If you already have multiple commits, you can add the commits together (squash them) with the following commands in Git Bash:
|
||||||
|
|
||||||
|
1. Open `Git Bash` (or `Git Shell`)
|
||||||
|
2. Enter following command to squash the recent {N} commits: `git reset --soft HEAD~{N} && git commit` (replace `{N}` with the number of commits you want to squash)
|
||||||
|
3. Press <kbd>i</kbd> to get into Insert-mode
|
||||||
|
4. Enter the commit message of the new commit (and add the [signature](#sign-your-work) at the and)
|
||||||
|
5. After adding the message, press <kbd>ESC</kbd> to get out of the Insert-mode
|
||||||
|
6. Write `:wq` and press <kbd>Enter</kbd> to save the new message or write `:q!` to discard your changes
|
||||||
|
7. Enter `git push --force` to push the new commit to the remote repository
|
||||||
|
|
||||||
|
For example, if you want to squash the last 5 commits, use `git reset --soft HEAD~5 && git commit`
|
||||||
|
|
||||||
### Don't mix code changes with whitespace cleanup
|
### Don't mix code changes with whitespace cleanup
|
||||||
|
|
||||||
If you change two lines of code and correct 200 lines of whitespace issues in a file the diff on that pull request is functionally unreadable and will be **rejected**. Whitespace cleanups need to be in their own pull request.
|
If you change two lines of code and correct 200 lines of whitespace issues in a file the diff on that pull request is functionally unreadable and will be **rejected**. Whitespace cleanups need to be in their own pull request.
|
26
.github/ISSUE_TEMPLATE.md
vendored
Normal file
26
.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<!--
|
||||||
|
Thanks for reporting issues of Telegram Desktop!
|
||||||
|
|
||||||
|
To make it easier for us to help you please enter detailed information below.
|
||||||
|
-->
|
||||||
|
### Steps to reproduce
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
### Expected behaviour
|
||||||
|
Tell us what should happen
|
||||||
|
|
||||||
|
### Actual behaviour
|
||||||
|
Tell us what happens instead
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
**Operating system:**
|
||||||
|
|
||||||
|
**Version of Telegram Desktop:**
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
Insert logs here (if necessary)
|
||||||
|
|
||||||
|
You can type "debugmode" in settings and then see ~/.TelegramDesktop/DebugLogs/log_...txt for log files.
|
||||||
|
Type "debugmode" in settings again to disable logs.
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -7,9 +7,11 @@
|
||||||
/Telegram/SourceFiles/art/sprite_125x.png
|
/Telegram/SourceFiles/art/sprite_125x.png
|
||||||
/Telegram/SourceFiles/art/sprite_150x.png
|
/Telegram/SourceFiles/art/sprite_150x.png
|
||||||
/Telegram/*.user
|
/Telegram/*.user
|
||||||
|
*.vcxproj.user
|
||||||
*.suo
|
*.suo
|
||||||
*.sdf
|
*.sdf
|
||||||
*.opensdf
|
*.opensdf
|
||||||
|
*.opendb
|
||||||
/Telegram/*.aps
|
/Telegram/*.aps
|
||||||
/Win32/
|
/Win32/
|
||||||
ipch/
|
ipch/
|
||||||
|
|
47
.travis.yml
Normal file
47
.travis.yml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
sudo: required
|
||||||
|
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
env:
|
||||||
|
- BUILD_VERSION=""
|
||||||
|
- BUILD_VERSION="disable_autoupdate"
|
||||||
|
- BUILD_VERSION="disable_register_custom_scheme"
|
||||||
|
- BUILD_VERSION="disable_crash_reports"
|
||||||
|
- BUILD_VERSION="disable_network_proxy"
|
||||||
|
|
||||||
|
arch:
|
||||||
|
packages:
|
||||||
|
- bzr
|
||||||
|
- wget
|
||||||
|
- qt5-base
|
||||||
|
|
||||||
|
- git
|
||||||
|
- patch
|
||||||
|
- libunity
|
||||||
|
- libappindicator-gtk2
|
||||||
|
|
||||||
|
- ffmpeg
|
||||||
|
- icu
|
||||||
|
- jasper
|
||||||
|
- libexif
|
||||||
|
- libmng
|
||||||
|
- libwebp
|
||||||
|
- libxkbcommon-x11
|
||||||
|
- libinput
|
||||||
|
- libproxy
|
||||||
|
- mtdev
|
||||||
|
- openal
|
||||||
|
- libva
|
||||||
|
- desktop-file-utils
|
||||||
|
- gtk-update-icon-cache
|
||||||
|
|
||||||
|
script:
|
||||||
|
- libtool --finish /usr/lib
|
||||||
|
- .travis/build.sh
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- "export TRAVIS_COMMIT_MSG=\"$(git log --format=%B --no-merges -n 1)\""
|
||||||
|
- .travis/check.sh
|
||||||
|
|
||||||
|
script:
|
||||||
|
- .travis/arch.sh
|
297
.travis/arch.sh
Executable file
297
.travis/arch.sh
Executable file
|
@ -0,0 +1,297 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright (C) 2016 Mikkel Oscar Lyderik Larsen
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Source: https://raw.githubusercontent.com/mikkeloscar/arch-travis/master/arch-travis.sh
|
||||||
|
|
||||||
|
# Script for setting up and running a travis-ci build in an up to date
|
||||||
|
# Arch Linux chroot
|
||||||
|
|
||||||
|
ARCH_TRAVIS_MIRROR=${ARCH_TRAVIS_MIRROR:-"https://lug.mtu.edu/archlinux"}
|
||||||
|
ARCH_TRAVIS_ARCH_ISO=${ARCH_TRAVIS_ARCH_ISO:-"$(date +%Y.%m).01"}
|
||||||
|
mirror_entry='Server = '$ARCH_TRAVIS_MIRROR'/\$repo/os/\$arch'
|
||||||
|
archive="archlinux-bootstrap-$ARCH_TRAVIS_ARCH_ISO-x86_64.tar.gz"
|
||||||
|
default_root="root.x86_64"
|
||||||
|
ARCH_TRAVIS_CHROOT=${ARCH_TRAVIS_CHROOT:-"$default_root"}
|
||||||
|
user="travis"
|
||||||
|
user_home="/home/$user"
|
||||||
|
user_build_dir="/build"
|
||||||
|
user_uid=$UID
|
||||||
|
|
||||||
|
if [ -n "$CC" ]; then
|
||||||
|
# store travis CC
|
||||||
|
TRAVIS_CC=$CC
|
||||||
|
# reset to gcc for building arch packages
|
||||||
|
CC=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# default packages
|
||||||
|
default_packages=("base-devel" "git")
|
||||||
|
|
||||||
|
# pacman.conf repository line
|
||||||
|
repo_line=70
|
||||||
|
|
||||||
|
# setup working Arch Linux chroot
|
||||||
|
setup_chroot() {
|
||||||
|
arch_msg "Setting up Arch chroot"
|
||||||
|
|
||||||
|
if [ ! -f $archive ]; then
|
||||||
|
# get root fs
|
||||||
|
curl --fail -O "$ARCH_TRAVIS_MIRROR/iso/$ARCH_TRAVIS_ARCH_ISO/$archive" 2>&1
|
||||||
|
local ret=$?
|
||||||
|
|
||||||
|
# if it fails, try arch iso form the previous month
|
||||||
|
if [ $ret -gt 0 ]; then
|
||||||
|
ARCH_TRAVIS_ARCH_ISO="$(date +%Y.%m -d "-1 month").01"
|
||||||
|
archive="archlinux-bootstrap-$ARCH_TRAVIS_ARCH_ISO-x86_64.tar.gz"
|
||||||
|
as_normal "curl -O $ARCH_TRAVIS_MIRROR/iso/$ARCH_TRAVIS_ARCH_ISO/$archive"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# extract root fs
|
||||||
|
as_root "tar xf $archive"
|
||||||
|
|
||||||
|
# remove archive if ARCH_TRAVIS_CLEAN_CHROOT is set
|
||||||
|
if [ -n "$ARCH_TRAVIS_CLEAN_CHROOT" ]; then
|
||||||
|
as_root "rm $archive"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ARCH_TRAVIS_CHROOT" != "$default_root" ]; then
|
||||||
|
as_root "mv $default_root $ARCH_TRAVIS_CHROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't care for signed packages
|
||||||
|
as_root "sed -i 's|SigLevel = Required DatabaseOptional|SigLevel = Never|' $ARCH_TRAVIS_CHROOT/etc/pacman.conf"
|
||||||
|
|
||||||
|
# enable multilib
|
||||||
|
as_root "sed -i 's|#\[multilib\]|\[multilib\]\nInclude = /etc/pacman.d/mirrorlist|' $ARCH_TRAVIS_CHROOT/etc/pacman.conf"
|
||||||
|
|
||||||
|
# add mirror
|
||||||
|
as_root "echo $mirror_entry >> $ARCH_TRAVIS_CHROOT/etc/pacman.d/mirrorlist"
|
||||||
|
|
||||||
|
# add nameserver to resolv.conf
|
||||||
|
as_root "echo nameserver 8.8.8.8 >> $ARCH_TRAVIS_CHROOT/etc/resolv.conf"
|
||||||
|
|
||||||
|
sudo mount $ARCH_TRAVIS_CHROOT $ARCH_TRAVIS_CHROOT --bind
|
||||||
|
sudo mount --bind /proc $ARCH_TRAVIS_CHROOT/proc
|
||||||
|
sudo mount --bind /sys $ARCH_TRAVIS_CHROOT/sys
|
||||||
|
sudo mount --bind /dev $ARCH_TRAVIS_CHROOT/dev
|
||||||
|
sudo mount --bind /dev/pts $ARCH_TRAVIS_CHROOT/dev/pts
|
||||||
|
sudo mount --bind /dev/shm $ARCH_TRAVIS_CHROOT/dev/shm
|
||||||
|
sudo mount --bind /run $ARCH_TRAVIS_CHROOT/run
|
||||||
|
|
||||||
|
# update packages
|
||||||
|
chroot_as_root "pacman -Syy"
|
||||||
|
chroot_as_root "pacman -Syu ${default_packages[*]} --noconfirm"
|
||||||
|
|
||||||
|
# use LANG=en_US.UTF-8 as expected in travis environments
|
||||||
|
as_root "sed -i 's|#en_US.UTF-8|en_US.UTF-8|' $ARCH_TRAVIS_CHROOT/etc/locale.gen"
|
||||||
|
chroot_as_root "locale-gen"
|
||||||
|
|
||||||
|
# setup non-root user
|
||||||
|
chroot_as_root "useradd -u $user_uid -m -s /bin/bash $user"
|
||||||
|
|
||||||
|
# disable password for sudo users
|
||||||
|
as_root "echo \"$user ALL=(ALL) NOPASSWD: ALL\" >> $ARCH_TRAVIS_CHROOT/etc/sudoers.d/$user"
|
||||||
|
|
||||||
|
# Add build dir
|
||||||
|
chroot_as_root "mkdir $user_build_dir && chown $user $user_build_dir"
|
||||||
|
|
||||||
|
# bind $TRAVIS_BUILD_DIR to chroot build dir
|
||||||
|
sudo mount --bind $TRAVIS_BUILD_DIR $ARCH_TRAVIS_CHROOT$user_build_dir
|
||||||
|
|
||||||
|
# add custom repos
|
||||||
|
add_repositories
|
||||||
|
|
||||||
|
# setup pacaur for AUR packages
|
||||||
|
setup_pacaur
|
||||||
|
}
|
||||||
|
|
||||||
|
# add custom repositories to pacman.conf
|
||||||
|
add_repositories() {
|
||||||
|
if [ ${#CONFIG_REPOS[@]} -gt 0 ]; then
|
||||||
|
for r in "${CONFIG_REPOS[@]}"; do
|
||||||
|
local splitarr=(${r//=/ })
|
||||||
|
((repo_line+=1))
|
||||||
|
as_root "sed -i '${repo_line}i[${splitarr[0]}]' $ARCH_TRAVIS_CHROOT/etc/pacman.conf"
|
||||||
|
((repo_line+=1))
|
||||||
|
as_root "sed -i '${repo_line}iServer = ${splitarr[1]}\n' $ARCH_TRAVIS_CHROOT/etc/pacman.conf"
|
||||||
|
((repo_line+=1))
|
||||||
|
done
|
||||||
|
|
||||||
|
# update repos
|
||||||
|
chroot_as_root "pacman -Syy"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# a wrapper which can be used to eventually add fakeroot support.
|
||||||
|
sudo_wrapper() {
|
||||||
|
sudo "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# run command as normal user
|
||||||
|
as_normal() {
|
||||||
|
local str="$@"
|
||||||
|
run /bin/bash -c "$str"
|
||||||
|
}
|
||||||
|
|
||||||
|
# run command as root
|
||||||
|
as_root() {
|
||||||
|
local str="$@"
|
||||||
|
run sudo_wrapper /bin/bash -c "$str"
|
||||||
|
}
|
||||||
|
|
||||||
|
# run command in chroot as root
|
||||||
|
chroot_as_root() {
|
||||||
|
local str="$@"
|
||||||
|
run sudo_wrapper chroot $ARCH_TRAVIS_CHROOT /bin/bash -c "$str"
|
||||||
|
}
|
||||||
|
|
||||||
|
# run command in chroot as normal user
|
||||||
|
chroot_as_normal() {
|
||||||
|
local str="$@"
|
||||||
|
run sudo_wrapper chroot --userspec=$user:$user $ARCH_TRAVIS_CHROOT /bin/bash \
|
||||||
|
-c "export HOME=$user_home USER=$user TRAVIS_BUILD_DIR=$user_build_dir && cd $user_build_dir && $str"
|
||||||
|
}
|
||||||
|
|
||||||
|
# run command
|
||||||
|
run() {
|
||||||
|
"$@"
|
||||||
|
local ret=$?
|
||||||
|
|
||||||
|
if [ $ret -gt 0 ]; then
|
||||||
|
takedown_chroot
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# run build script
|
||||||
|
run_build_script() {
|
||||||
|
local cmd="$@"
|
||||||
|
echo "$ $cmd"
|
||||||
|
sudo_wrapper chroot --userspec=$user:$user $ARCH_TRAVIS_CHROOT /bin/bash -c "export HOME=$user_home USER=$user TRAVIS_BUILD_DIR=$user_build_dir && cd $user_build_dir && $cmd"
|
||||||
|
local ret=$?
|
||||||
|
|
||||||
|
if [ $ret -gt 0 ]; then
|
||||||
|
takedown_chroot
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# setup pacaur
|
||||||
|
setup_pacaur() {
|
||||||
|
local cowerarchive="cower.tar.gz"
|
||||||
|
local aururl="https://aur.archlinux.org/cgit/aur.git/snapshot/"
|
||||||
|
# install cower
|
||||||
|
as_normal "curl -O $aururl/$cowerarchive"
|
||||||
|
as_normal "tar xf $cowerarchive"
|
||||||
|
chroot_as_normal "cd cower && makepkg -is --skippgpcheck --noconfirm"
|
||||||
|
as_root "rm -r cower"
|
||||||
|
as_normal "rm $cowerarchive"
|
||||||
|
# install pacaur
|
||||||
|
chroot_as_normal "cower -dd pacaur"
|
||||||
|
chroot_as_normal "cd pacaur && makepkg -is --noconfirm"
|
||||||
|
chroot_as_normal "rm -rf pacaur"
|
||||||
|
}
|
||||||
|
|
||||||
|
# install package through pacaur
|
||||||
|
_pacaur() {
|
||||||
|
local pacaur="pacaur -S $@ --noconfirm --noedit"
|
||||||
|
chroot_as_normal "$pacaur"
|
||||||
|
}
|
||||||
|
|
||||||
|
# takedown chroot
|
||||||
|
# unmounts anything mounted in the chroot setup
|
||||||
|
takedown_chroot() {
|
||||||
|
sudo umount $ARCH_TRAVIS_CHROOT/{run,dev/shm,dev/pts,dev,sys,proc}
|
||||||
|
sudo umount $ARCH_TRAVIS_CHROOT$user_build_dir
|
||||||
|
sudo umount $ARCH_TRAVIS_CHROOT
|
||||||
|
|
||||||
|
if [ -n "$ARCH_TRAVIS_CLEAN_CHROOT" ]; then
|
||||||
|
as_root "rm -rf $ARCH_TRAVIS_CHROOT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# read value from .travis.yml
|
||||||
|
travis_yml() {
|
||||||
|
ruby -ryaml -e 'puts ARGV[1..-1].inject(YAML.load(File.read(ARGV[0]))) {|acc, key| acc[key] }' .travis.yml $@
|
||||||
|
}
|
||||||
|
|
||||||
|
read_config() {
|
||||||
|
old_ifs=$IFS
|
||||||
|
IFS=$'\n'
|
||||||
|
CONFIG_BUILD_SCRIPTS=($(travis_yml arch script))
|
||||||
|
CONFIG_PACKAGES=($(travis_yml arch packages))
|
||||||
|
CONFIG_REPOS=($(travis_yml arch repos))
|
||||||
|
IFS=$old_ifs
|
||||||
|
}
|
||||||
|
|
||||||
|
# run build scripts defined in .travis.yml
|
||||||
|
build_scripts() {
|
||||||
|
if [ ${#CONFIG_BUILD_SCRIPTS[@]} -gt 0 ]; then
|
||||||
|
for script in "${CONFIG_BUILD_SCRIPTS[@]}"; do
|
||||||
|
run_build_script $script
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "No build scripts defined"
|
||||||
|
takedown_chroot
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# install packages defined in .travis.yml
|
||||||
|
install_packages() {
|
||||||
|
for package in "${CONFIG_PACKAGES[@]}"; do
|
||||||
|
_pacaur $package
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# install custom compiler if CC != gcc
|
||||||
|
install_c_compiler() {
|
||||||
|
if [ "$TRAVIS_CC" != "gcc" ]; then
|
||||||
|
_pacaur "$TRAVIS_CC"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_msg() {
|
||||||
|
lightblue='\033[1;34m'
|
||||||
|
reset='\e[0m'
|
||||||
|
echo -e "${lightblue}$@${reset}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# read .travis.yml
|
||||||
|
read_config
|
||||||
|
|
||||||
|
echo "travis_fold:start:arch_travis"
|
||||||
|
setup_chroot
|
||||||
|
|
||||||
|
install_packages
|
||||||
|
|
||||||
|
if [ -n "$CC" ]; then
|
||||||
|
install_c_compiler
|
||||||
|
|
||||||
|
# restore CC
|
||||||
|
CC=$TRAVIS_CC
|
||||||
|
fi
|
||||||
|
echo "travis_fold:end:arch_travis"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
arch_msg "Running travis build"
|
||||||
|
build_scripts
|
||||||
|
|
||||||
|
takedown_chroot
|
||||||
|
|
||||||
|
# vim:set ts=2 sw=2 et:
|
160
.travis/build.sh
Executable file
160
.travis/build.sh
Executable file
|
@ -0,0 +1,160 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Installs libs and compiles tdesktop
|
||||||
|
|
||||||
|
run() {
|
||||||
|
info_msg "Build version: ${BUILD_VERSION}"
|
||||||
|
|
||||||
|
downloadLibs
|
||||||
|
prepare
|
||||||
|
build
|
||||||
|
check
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadLibs() {
|
||||||
|
travis_fold_start "download_libs"
|
||||||
|
# Move telegram project to subfolder
|
||||||
|
mkdir tdesktop
|
||||||
|
mv -f Telegram tdesktop
|
||||||
|
|
||||||
|
# Download libraries
|
||||||
|
info_msg "QT-Version: ${_qtver}, SRC-Dir: ${srcdir}"
|
||||||
|
|
||||||
|
echo -e "\nDownload and extract qt"
|
||||||
|
qt_file=qt-everywhere-opensource-src-$_qtver.tar.xz
|
||||||
|
echo -e "QT-File: ${qt_file}"
|
||||||
|
|
||||||
|
wget "http://download.qt.io/official_releases/qt/${_qtver%.*}/$_qtver/single/$qt_file"
|
||||||
|
tar xf $qt_file
|
||||||
|
rm $qt_file
|
||||||
|
|
||||||
|
echo -e "Clone Breakpad"
|
||||||
|
git clone https://chromium.googlesource.com/breakpad/breakpad breakpad
|
||||||
|
|
||||||
|
echo -e "\nClone Linux Syscall Support"
|
||||||
|
git clone https://chromium.googlesource.com/linux-syscall-support breakpad-lss
|
||||||
|
|
||||||
|
echo -e "\nLets view the folder content"
|
||||||
|
ls
|
||||||
|
travis_fold_end "download_libs"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
travis_fold_start "prepare"
|
||||||
|
start_msg "Preparing the libraries..."
|
||||||
|
|
||||||
|
cd "$srcdir/tdesktop"
|
||||||
|
|
||||||
|
mkdir -p "$srcdir/Libraries"
|
||||||
|
|
||||||
|
local qt_patch_file="$srcdir/tdesktop/Telegram/_qtbase_${_qtver//./_}_patch.diff"
|
||||||
|
if [ "$qt_patch_file" -nt "$srcdir/Libraries/QtStatic" ]; then
|
||||||
|
rm -rf "$srcdir/Libraries/QtStatic"
|
||||||
|
mv "$srcdir/qt-everywhere-opensource-src-$_qtver" "$srcdir/Libraries/QtStatic"
|
||||||
|
cd "$srcdir/Libraries/QtStatic/qtbase"
|
||||||
|
patch -p1 -i "$qt_patch_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -h "$srcdir/Libraries/breakpad" ]; then
|
||||||
|
ln -s "$srcdir/breakpad" "$srcdir/Libraries/breakpad"
|
||||||
|
ln -s "$srcdir/breakpad-lss" "$srcdir/Libraries/breakpad/src/third_party/lss"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i 's/CUSTOM_API_ID//g' "$srcdir/tdesktop/Telegram/Telegram.pro"
|
||||||
|
sed -i 's,LIBS += /usr/local/lib/libxkbcommon.a,,g' "$srcdir/tdesktop/Telegram/Telegram.pro"
|
||||||
|
sed -i 's,LIBS += /usr/local/lib/libz.a,LIBS += -lz,g' "$srcdir/tdesktop/Telegram/Telegram.pro"
|
||||||
|
|
||||||
|
local options=""
|
||||||
|
|
||||||
|
if [[ $BUILD_VERSION == *"disable_autoupdate"* ]]; then
|
||||||
|
options+="\nDEFINES += TDESKTOP_DISABLE_AUTOUPDATE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $BUILD_VERSION == *"disable_register_custom_scheme"* ]]; then
|
||||||
|
options+="\nDEFINES += TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $BUILD_VERSION == *"disable_crash_reports"* ]]; then
|
||||||
|
options+="\nDEFINES += TDESKTOP_DISABLE_CRASH_REPORTS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $BUILD_VERSION == *"disable_network_proxy"* ]]; then
|
||||||
|
options+="\nDEFINES += TDESKTOP_DISABLE_NETWORK_PROXY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
options+='\nINCLUDEPATH += "/usr/lib/glib-2.0/include"'
|
||||||
|
options+='\nINCLUDEPATH += "/usr/lib/gtk-2.0/include"'
|
||||||
|
options+='\nINCLUDEPATH += "/usr/include/opus"'
|
||||||
|
options+='\nLIBS += -lcrypto -lssl'
|
||||||
|
|
||||||
|
info_msg "Build options: ${options}"
|
||||||
|
|
||||||
|
echo -e "${options}" >> "$srcdir/tdesktop/Telegram/Telegram.pro"
|
||||||
|
|
||||||
|
success_msg "Prepare done! :)"
|
||||||
|
travis_fold_end "prepare"
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
start_msg "Building the projects..."
|
||||||
|
|
||||||
|
info_msg "Build patched Qt"
|
||||||
|
# Build patched Qt
|
||||||
|
cd "$srcdir/Libraries/QtStatic"
|
||||||
|
./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \
|
||||||
|
-qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \
|
||||||
|
-qt-xkbcommon-x11 -no-opengl -static -nomake examples -nomake tests
|
||||||
|
make --silent module-qtbase module-qtimageformats
|
||||||
|
make --silent module-qtbase-install_subtargets module-qtimageformats-install_subtargets
|
||||||
|
|
||||||
|
export PATH="$srcdir/qt/bin:$PATH"
|
||||||
|
|
||||||
|
info_msg "Build breakpad"
|
||||||
|
# Build breakpad
|
||||||
|
cd "$srcdir/Libraries/breakpad"
|
||||||
|
./configure
|
||||||
|
make --silent
|
||||||
|
|
||||||
|
info_msg "Build MetaStyle"
|
||||||
|
# Build MetaStyle
|
||||||
|
mkdir -p "$srcdir/tdesktop/Linux/DebugIntermediateStyle"
|
||||||
|
cd "$srcdir/tdesktop/Linux/DebugIntermediateStyle"
|
||||||
|
qmake CONFIG+=debug "../../Telegram/MetaStyle.pro"
|
||||||
|
make --silent
|
||||||
|
|
||||||
|
info_msg "Build MetaLang"
|
||||||
|
# Build MetaLang
|
||||||
|
mkdir -p "$srcdir/tdesktop/Linux/DebugIntermediateLang"
|
||||||
|
cd "$srcdir/tdesktop/Linux/DebugIntermediateLang"
|
||||||
|
qmake CONFIG+=debug "../../Telegram/MetaLang.pro"
|
||||||
|
make --silent
|
||||||
|
|
||||||
|
info_msg "Build Telegram Desktop"
|
||||||
|
# Build Telegram Desktop
|
||||||
|
mkdir -p "$srcdir/tdesktop/Linux/ReleaseIntermediate"
|
||||||
|
cd "$srcdir/tdesktop/Linux/ReleaseIntermediate"
|
||||||
|
|
||||||
|
qmake CONFIG+=release "../../Telegram/Telegram.pro"
|
||||||
|
local pattern="^PRE_TARGETDEPS +="
|
||||||
|
grep "$pattern" "$srcdir/tdesktop/Telegram/Telegram.pro" | sed "s/$pattern//g" | xargs make
|
||||||
|
|
||||||
|
qmake CONFIG+=release "../../Telegram/Telegram.pro"
|
||||||
|
make
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
local filePath="$srcdir/tdesktop/Linux/Release/Telegram"
|
||||||
|
if test -f "$filePath"; then
|
||||||
|
success_msg "Build successful done! :)"
|
||||||
|
|
||||||
|
local size;
|
||||||
|
size=$(stat -c %s "$filePath")
|
||||||
|
success_msg "File size of ${filePath}: ${size} Bytes"
|
||||||
|
else
|
||||||
|
error_msg "Build error, output file does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
source ./.travis/common.sh
|
||||||
|
|
||||||
|
run
|
25
.travis/check.sh
Executable file
25
.travis/check.sh
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Checks commit message, ...
|
||||||
|
|
||||||
|
run() {
|
||||||
|
checkCommitMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCommitMessage() {
|
||||||
|
info_msg "Commit message: ${TRAVIS_COMMIT_MSG}";
|
||||||
|
info_msg "Is pull request: ${TRAVIS_PULL_REQUEST}";
|
||||||
|
|
||||||
|
if [[ $TRAVIS_PULL_REQUEST != "false" ]];then
|
||||||
|
if [[ $TRAVIS_COMMIT_MSG != *"Signed-off-by: "* ]];then
|
||||||
|
error_msg "The commit message does not contain the signature!"
|
||||||
|
error_msg "More information: https://github.com/telegramdesktop/tdesktop/blob/master/.github/CONTRIBUTING.md#sign-your-work"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
success_msg "Commit message contains signature"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
source ./.travis/common.sh
|
||||||
|
|
||||||
|
run
|
40
.travis/common.sh
Executable file
40
.travis/common.sh
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
# set colors
|
||||||
|
RCol='\e[0m' # Text Reset
|
||||||
|
|
||||||
|
# Regular Bold Underline High Intensity BoldHigh Intens Background High Intensity Backgrounds
|
||||||
|
Bla='\e[0;30m'; BBla='\e[1;30m'; UBla='\e[4;30m'; IBla='\e[0;90m'; BIBla='\e[1;90m'; On_Bla='\e[40m'; On_IBla='\e[0;100m';
|
||||||
|
Red='\e[0;31m'; BRed='\e[1;31m'; URed='\e[4;31m'; IRed='\e[0;91m'; BIRed='\e[1;91m'; On_Red='\e[41m'; On_IRed='\e[0;101m';
|
||||||
|
Gre='\e[0;32m'; BGre='\e[1;32m'; UGre='\e[4;32m'; IGre='\e[0;92m'; BIGre='\e[1;92m'; On_Gre='\e[42m'; On_IGre='\e[0;102m';
|
||||||
|
Yel='\e[0;33m'; BYel='\e[1;33m'; UYel='\e[4;33m'; IYel='\e[0;93m'; BIYel='\e[1;93m'; On_Yel='\e[43m'; On_IYel='\e[0;103m';
|
||||||
|
Blu='\e[0;34m'; BBlu='\e[1;34m'; UBlu='\e[4;34m'; IBlu='\e[0;94m'; BIBlu='\e[1;94m'; On_Blu='\e[44m'; On_IBlu='\e[0;104m';
|
||||||
|
Pur='\e[0;35m'; BPur='\e[1;35m'; UPur='\e[4;35m'; IPur='\e[0;95m'; BIPur='\e[1;95m'; On_Pur='\e[45m'; On_IPur='\e[0;105m';
|
||||||
|
Cya='\e[0;36m'; BCya='\e[1;36m'; UCya='\e[4;36m'; ICya='\e[0;96m'; BICya='\e[1;96m'; On_Cya='\e[46m'; On_ICya='\e[0;106m';
|
||||||
|
Whi='\e[0;37m'; BWhi='\e[1;37m'; UWhi='\e[4;37m'; IWhi='\e[0;97m'; BIWhi='\e[1;97m'; On_Whi='\e[47m'; On_IWhi='\e[0;107m';
|
||||||
|
|
||||||
|
# Set variables
|
||||||
|
_qtver=5.5.1
|
||||||
|
srcdir=${PWD}
|
||||||
|
|
||||||
|
start_msg() {
|
||||||
|
echo -e "\n${Gre}$*${RCol}"
|
||||||
|
}
|
||||||
|
|
||||||
|
info_msg() {
|
||||||
|
echo -e "\n${Cya}$*${RCol}"
|
||||||
|
}
|
||||||
|
|
||||||
|
error_msg() {
|
||||||
|
echo -e "\n${BRed}$*${RCol}"
|
||||||
|
}
|
||||||
|
|
||||||
|
success_msg() {
|
||||||
|
echo -e "\n${BGre}$*${RCol}"
|
||||||
|
}
|
||||||
|
|
||||||
|
travis_fold_start() {
|
||||||
|
echo "travis_fold:start:$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
travis_fold_end() {
|
||||||
|
echo "travis_fold:end:$*"
|
||||||
|
}
|
35
README.md
35
README.md
|
@ -2,14 +2,16 @@
|
||||||
|
|
||||||
This is the complete source code and the build instructions for the alpha version of the official desktop client for the [Telegram][telegram] messenger, based on the [Telegram API][telegram_api] and the [MTProto][telegram_proto] secure protocol.
|
This is the complete source code and the build instructions for the alpha version of the official desktop client for the [Telegram][telegram] messenger, based on the [Telegram API][telegram_api] and the [MTProto][telegram_proto] secure protocol.
|
||||||
|
|
||||||
|
[](https://travis-ci.org/telegramdesktop/tdesktop)
|
||||||
|
|
||||||
The source code is published under GPLv3 with OpenSSL exception, the license is available [here][license].
|
The source code is published under GPLv3 with OpenSSL exception, the license is available [here][license].
|
||||||
|
|
||||||
## Supported systems
|
## Supported systems
|
||||||
|
|
||||||
* Windows XP - Windows 10 (**not** RT)
|
* Windows XP - Windows 10 (**not** RT)
|
||||||
* Mac OS X 10.8 - Mac OS X 10.10
|
* Mac OS X 10.8 - Mac OS X 10.11
|
||||||
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
|
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
|
||||||
* Ubuntu 12.04 - Ubuntu 14.04
|
* Ubuntu 12.04 - Ubuntu 15.04
|
||||||
* Fedora 22
|
* Fedora 22
|
||||||
|
|
||||||
## Third-party libraries
|
## Third-party libraries
|
||||||
|
@ -20,6 +22,8 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||||
* libexif 0.6.20 ([LGPL](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html))
|
* libexif 0.6.20 ([LGPL](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html))
|
||||||
* LZMA SDK 9.20 ([public domain](http://www.7-zip.org/sdk.html))
|
* LZMA SDK 9.20 ([public domain](http://www.7-zip.org/sdk.html))
|
||||||
* liblzma ([public domain](http://tukaani.org/xz/))
|
* liblzma ([public domain](http://tukaani.org/xz/))
|
||||||
|
* Google Breakpad ([License](https://chromium.googlesource.com/breakpad/breakpad/+/master/LICENSE))
|
||||||
|
* Google Crashpad ([Apache License 2.0](https://chromium.googlesource.com/crashpad/crashpad/+/master/LICENSE))
|
||||||
* OpenAL Soft ([LGPL](http://kcat.strangesoft.net/openal.html))
|
* OpenAL Soft ([LGPL](http://kcat.strangesoft.net/openal.html))
|
||||||
* Opus codec ([BSD license](http://www.opus-codec.org/license/))
|
* Opus codec ([BSD license](http://www.opus-codec.org/license/))
|
||||||
* FFmpeg ([LGPL](https://www.ffmpeg.org/legal.html))
|
* FFmpeg ([LGPL](https://www.ffmpeg.org/legal.html))
|
||||||
|
@ -31,6 +35,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||||
* [XCode 7][xcode]
|
* [XCode 7][xcode]
|
||||||
* [XCode 7 for OS X 10.6 and 10.7][xcode_old]
|
* [XCode 7 for OS X 10.6 and 10.7][xcode_old]
|
||||||
* [Qt Creator 3.5.1 Ubuntu][qtcreator]
|
* [Qt Creator 3.5.1 Ubuntu][qtcreator]
|
||||||
|
* [Using qmake on GNU/Linux][qmake]
|
||||||
|
|
||||||
## Projects in Telegram solution
|
## Projects in Telegram solution
|
||||||
|
|
||||||
|
@ -46,21 +51,6 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||||
|
|
||||||
Compiles given files to single update file, compresses it with lzma and signs with a private key. It is not built in **Debug** and **Release** configurations of Telegram solution, because private key is inaccessible.
|
Compiles given files to single update file, compresses it with lzma and signs with a private key. It is not built in **Debug** and **Release** configurations of Telegram solution, because private key is inaccessible.
|
||||||
|
|
||||||
* ### Prepare
|
|
||||||
|
|
||||||
Prepares a release for deployment, puts all current files to deploy/{version} folder.
|
|
||||||
|
|
||||||
**Windows**:
|
|
||||||
* tsetup{version}.exe installer
|
|
||||||
* Telegram.exe
|
|
||||||
* Telegram.pdb (debug info for crash minidumps view)
|
|
||||||
* tupdate{updversion} binary lzma update archive
|
|
||||||
|
|
||||||
**Mac**:
|
|
||||||
* tsetup{version}.dmg
|
|
||||||
* Telegram.app
|
|
||||||
* tmacupd{updversion} binary lzma update archive
|
|
||||||
|
|
||||||
* ### MetaEmoji
|
* ### MetaEmoji
|
||||||
|
|
||||||
Creates four sprites and text2emoji replace code
|
Creates four sprites and text2emoji replace code
|
||||||
|
@ -92,7 +82,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||||
|
|
||||||
* ### MetaLang
|
* ### MetaLang
|
||||||
|
|
||||||
Creates from languagepack file `Resources/lang.txt` language constants code and language file parse code:
|
Creates from languagepack file `Resources/lang.strings` language constants code and language file parse code:
|
||||||
* GeneratedFiles/lang.h
|
* GeneratedFiles/lang.h
|
||||||
* GeneratedFiles/lang.cpp
|
* GeneratedFiles/lang.cpp
|
||||||
|
|
||||||
|
@ -102,7 +92,8 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||||
[telegram_api]: https://core.telegram.org
|
[telegram_api]: https://core.telegram.org
|
||||||
[telegram_proto]: https://core.telegram.org/mtproto
|
[telegram_proto]: https://core.telegram.org/mtproto
|
||||||
[license]: LICENSE
|
[license]: LICENSE
|
||||||
[msvc]: MSVC.md
|
[msvc]: doc/building-msvc.md
|
||||||
[xcode]: XCODE.md
|
[xcode]: doc/building-xcode.md
|
||||||
[xcode_old]: XCODEold.md
|
[xcode_old]: doc/building-xcode-old.md
|
||||||
[qtcreator]: QTCREATOR.md
|
[qtcreator]: doc/building-qtcreator.md
|
||||||
|
[qmake]: doc/building-qmake.md
|
||||||
|
|
21
Telegram.sln
21
Telegram.sln
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2013
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 12.0.30501.0
|
VisualStudioVersion = 14.0.24720.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Telegram", "Telegram\Telegram.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Telegram", "Telegram\Telegram.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
@ -18,10 +18,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Updater", "Telegram\Updater
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MetaLang", "Telegram\MetaLang.vcxproj", "{E417CAA4-259B-4C99-88E3-805F1300E8EB}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MetaLang", "Telegram\MetaLang.vcxproj", "{E417CAA4-259B-4C99-88E3-805F1300E8EB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2F863EAD-33C9-4014-A573-93F085BA9CB1}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "codegen", "codegen", "{2F863EAD-33C9-4014-A573-93F085BA9CB1}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Packer", "Telegram\Packer.vcxproj", "{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Packer", "Telegram\Packer.vcxproj", "{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "codegen_style", "Telegram\build\vc\codegen_style\codegen_style.vcxproj", "{E4DF8176-4DEF-4859-962F-B497E3E7A323}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
@ -82,8 +84,21 @@ Global
|
||||||
{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}.Deploy|x64.ActiveCfg = Release|Win32
|
{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}.Deploy|x64.ActiveCfg = Release|Win32
|
||||||
{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}.Release|Win32.ActiveCfg = Release|Win32
|
{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}.Release|x64.ActiveCfg = Release|Win32
|
{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}.Release|x64.ActiveCfg = Release|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Debug|x64.ActiveCfg = Debug|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Deploy|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Deploy|Win32.Build.0 = Debug|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Deploy|x64.ActiveCfg = Release|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Deploy|x64.Build.0 = Release|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323}.Release|x64.ActiveCfg = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323} = {2F863EAD-33C9-4014-A573-93F085BA9CB1}
|
||||||
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@echo OFF
|
@echo OFF
|
||||||
|
setlocal
|
||||||
|
|
||||||
FOR /F "tokens=1,2* delims= " %%i in (Version) do set "%%i=%%j"
|
FOR /F "tokens=1,2* delims= " %%i in (Version) do set "%%i=%%j"
|
||||||
|
|
||||||
|
@ -29,6 +30,8 @@ set "HomePath=..\..\Telegram"
|
||||||
set "ReleasePath=..\Win32\Deploy"
|
set "ReleasePath=..\Win32\Deploy"
|
||||||
set "DeployPath=%ReleasePath%\deploy\%AppVersionStrMajor%\%AppVersionStrFull%"
|
set "DeployPath=%ReleasePath%\deploy\%AppVersionStrMajor%\%AppVersionStrFull%"
|
||||||
set "SignPath=..\..\TelegramPrivate\Sign.bat"
|
set "SignPath=..\..\TelegramPrivate\Sign.bat"
|
||||||
|
set "BinaryName=Telegram"
|
||||||
|
set "DropboxSymbolsPath=Z:\Dropbox\Telegram\symbols"
|
||||||
|
|
||||||
if %BetaVersion% neq 0 (
|
if %BetaVersion% neq 0 (
|
||||||
if exist %DeployPath%\ (
|
if exist %DeployPath%\ (
|
||||||
|
@ -71,9 +74,13 @@ echo .
|
||||||
echo Version %AppVersionStrFull% build successfull. Preparing..
|
echo Version %AppVersionStrFull% build successfull. Preparing..
|
||||||
echo .
|
echo .
|
||||||
|
|
||||||
|
echo Dumping debug symbols..
|
||||||
|
call ..\..\Libraries\breakpad\src\tools\windows\binaries\dump_syms.exe %ReleasePath%\%BinaryName%.pdb > %ReleasePath%\%BinaryName%.sym
|
||||||
|
echo Done!
|
||||||
|
|
||||||
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"
|
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"
|
||||||
|
|
||||||
call %SignPath% %ReleasePath%\Telegram.exe
|
call %SignPath% %ReleasePath%\%BinaryName%.exe
|
||||||
if %errorlevel% neq 0 goto error
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
call %SignPath% %ReleasePath%\Updater.exe
|
call %SignPath% %ReleasePath%\Updater.exe
|
||||||
|
@ -90,7 +97,7 @@ if %BetaVersion% equ 0 (
|
||||||
)
|
)
|
||||||
|
|
||||||
cd %ReleasePath%
|
cd %ReleasePath%
|
||||||
call Packer.exe -version %VersionForPacker% -path Telegram.exe -path Updater.exe %DevParam%
|
call Packer.exe -version %VersionForPacker% -path %BinaryName%.exe -path Updater.exe %DevParam%
|
||||||
cd %HomePath%
|
cd %HomePath%
|
||||||
if %errorlevel% neq 0 goto error
|
if %errorlevel% neq 0 goto error
|
||||||
|
|
||||||
|
@ -109,6 +116,21 @@ if %BetaVersion% neq 0 (
|
||||||
set "PortableFile=tbeta%BetaVersion%_%BetaSignature%.zip"
|
set "PortableFile=tbeta%BetaVersion%_%BetaSignature%.zip"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for /f ^"usebackq^ eol^=^
|
||||||
|
|
||||||
|
^ delims^=^" %%a in (%ReleasePath%\%BinaryName%.sym) do (
|
||||||
|
set "SymbolsHashLine=%%a"
|
||||||
|
goto symbolslinedone
|
||||||
|
)
|
||||||
|
:symbolslinedone
|
||||||
|
FOR /F "tokens=1,2,3,4* delims= " %%i in ("%SymbolsHashLine%") do set "SymbolsHash=%%l"
|
||||||
|
|
||||||
|
echo Copying %BinaryName%.sym to %DropboxSymbolsPath%\%BinaryName%.pdb\%SymbolsHash%
|
||||||
|
if not exist %DropboxSymbolsPath%\%BinaryName%.pdb mkdir %DropboxSymbolsPath%\%BinaryName%.pdb
|
||||||
|
if not exist %DropboxSymbolsPath%\%BinaryName%.pdb\%SymbolsHash% mkdir %DropboxSymbolsPath%\%BinaryName%.pdb\%SymbolsHash%
|
||||||
|
xcopy %ReleasePath%\%BinaryName%.sym %DropboxSymbolsPath%\%BinaryName%.pdb\%SymbolsHash%\
|
||||||
|
echo Done!
|
||||||
|
|
||||||
if not exist %ReleasePath%\deploy mkdir %ReleasePath%\deploy
|
if not exist %ReleasePath%\deploy mkdir %ReleasePath%\deploy
|
||||||
if not exist %ReleasePath%\deploy\%AppVersionStrMajor% mkdir %ReleasePath%\deploy\%AppVersionStrMajor%
|
if not exist %ReleasePath%\deploy\%AppVersionStrMajor% mkdir %ReleasePath%\deploy\%AppVersionStrMajor%
|
||||||
mkdir %DeployPath%
|
mkdir %DeployPath%
|
||||||
|
@ -144,7 +166,7 @@ if not exist %DeployPath%\%PortableFile% goto error
|
||||||
if %BetaVersion% equ 0 (
|
if %BetaVersion% equ 0 (
|
||||||
if not exist %DeployPath%\%SetupFile% goto error
|
if not exist %DeployPath%\%SetupFile% goto error
|
||||||
)
|
)
|
||||||
if not exist %DeployPath%\Telegram.pdb goto error
|
if not exist %DeployPath%\%BinaryName%.pdb goto error
|
||||||
if not exist %DeployPath%\Updater.exe goto error
|
if not exist %DeployPath%\Updater.exe goto error
|
||||||
if not exist %DeployPath%\Updater.pdb goto error
|
if not exist %DeployPath%\Updater.pdb goto error
|
||||||
if not exist %FinalReleasePath%\%AppVersionStrMajor% mkdir %FinalReleasePath%\%AppVersionStrMajor%
|
if not exist %FinalReleasePath%\%AppVersionStrMajor% mkdir %FinalReleasePath%\%AppVersionStrMajor%
|
||||||
|
@ -157,7 +179,7 @@ if %BetaVersion% equ 0 (
|
||||||
) else (
|
) else (
|
||||||
xcopy %DeployPath%\%BetaKeyFile% %FinalDeployPath%\ /Y
|
xcopy %DeployPath%\%BetaKeyFile% %FinalDeployPath%\ /Y
|
||||||
)
|
)
|
||||||
xcopy %DeployPath%\Telegram.pdb %FinalDeployPath%\
|
xcopy %DeployPath%\%BinaryName%.pdb %FinalDeployPath%\
|
||||||
xcopy %DeployPath%\Updater.exe %FinalDeployPath%\
|
xcopy %DeployPath%\Updater.exe %FinalDeployPath%\
|
||||||
xcopy %DeployPath%\Updater.pdb %FinalDeployPath%\
|
xcopy %DeployPath%\Updater.pdb %FinalDeployPath%\
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
FastParam="$1"
|
||||||
|
|
||||||
while IFS='' read -r line || [[ -n "$line" ]]; do
|
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
set $line
|
set $line
|
||||||
eval $1="$2"
|
eval $1="$2"
|
||||||
|
@ -37,6 +39,7 @@ if [ "$BuildTarget" == "linux" ]; then
|
||||||
WorkPath="./../Linux"
|
WorkPath="./../Linux"
|
||||||
FixScript="$HomePath/FixMake.sh"
|
FixScript="$HomePath/FixMake.sh"
|
||||||
ReleasePath="./../Linux/Release"
|
ReleasePath="./../Linux/Release"
|
||||||
|
BinaryName="Telegram"
|
||||||
elif [ "$BuildTarget" == "linux32" ]; then
|
elif [ "$BuildTarget" == "linux32" ]; then
|
||||||
echo "Building version $AppVersionStrFull for Linux 32bit.."
|
echo "Building version $AppVersionStrFull for Linux 32bit.."
|
||||||
UpdateFile="tlinux32upd$AppVersion"
|
UpdateFile="tlinux32upd$AppVersion"
|
||||||
|
@ -44,6 +47,7 @@ elif [ "$BuildTarget" == "linux32" ]; then
|
||||||
WorkPath="./../Linux"
|
WorkPath="./../Linux"
|
||||||
FixScript="$HomePath/FixMake32.sh"
|
FixScript="$HomePath/FixMake32.sh"
|
||||||
ReleasePath="./../Linux/Release"
|
ReleasePath="./../Linux/Release"
|
||||||
|
BinaryName="Telegram"
|
||||||
elif [ "$BuildTarget" == "mac" ]; then
|
elif [ "$BuildTarget" == "mac" ]; then
|
||||||
echo "Building version $AppVersionStrFull for OS X 10.8+.."
|
echo "Building version $AppVersionStrFull for OS X 10.8+.."
|
||||||
UpdateFile="tmacupd$AppVersion"
|
UpdateFile="tmacupd$AppVersion"
|
||||||
|
@ -104,22 +108,25 @@ fi
|
||||||
#fi
|
#fi
|
||||||
|
|
||||||
if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
||||||
|
|
||||||
|
DropboxSymbolsPath="/media/psf/Home/Dropbox/Telegram/symbols"
|
||||||
|
|
||||||
mkdir -p "$WorkPath/ReleaseIntermediateUpdater"
|
mkdir -p "$WorkPath/ReleaseIntermediateUpdater"
|
||||||
cd "$WorkPath/ReleaseIntermediateUpdater"
|
cd "$WorkPath/ReleaseIntermediateUpdater"
|
||||||
/usr/local/Qt-5.5.1/bin/qmake "$HomePath/Updater.pro"
|
/usr/local/Qt-5.5.1/bin/qmake "$HomePath/Updater.pro" -r -spec linux-g++
|
||||||
make
|
make
|
||||||
echo "Updater build complete!"
|
echo "Updater build complete!"
|
||||||
cd "$HomePath"
|
cd "$HomePath"
|
||||||
|
|
||||||
mkdir -p "$WorkPath/ReleaseIntermediate"
|
mkdir -p "$WorkPath/ReleaseIntermediate"
|
||||||
cd "$WorkPath/ReleaseIntermediate"
|
cd "$WorkPath/ReleaseIntermediate"
|
||||||
/usr/local/Qt-5.5.1/bin/qmake "$HomePath/Telegram.pro"
|
/usr/local/Qt-5.5.1/bin/qmake "$HomePath/Telegram.pro" -r -spec linux-g++
|
||||||
eval "$FixScript"
|
eval "$FixScript"
|
||||||
make
|
make
|
||||||
echo "Telegram build complete!"
|
echo "$BinaryName build complete!"
|
||||||
cd "$HomePath"
|
cd "$HomePath"
|
||||||
if [ ! -f "$ReleasePath/Telegram" ]; then
|
if [ ! -f "$ReleasePath/$BinaryName" ]; then
|
||||||
echo "Telegram not found!"
|
echo "$BinaryName not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -128,8 +135,16 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Dumping debug symbols.."
|
||||||
|
"./../../Libraries/breakpad/src/tools/linux/dump_syms/dump_syms" "$ReleasePath/$BinaryName" > "$ReleasePath/$BinaryName.sym"
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
|
echo "Stripping the executable.."
|
||||||
|
strip -s "$ReleasePath/$BinaryName"
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
echo "Preparing version $AppVersionStrFull, executing Packer.."
|
echo "Preparing version $AppVersionStrFull, executing Packer.."
|
||||||
cd "$ReleasePath" && "./Packer" -path Telegram -path Updater -version $VersionForPacker $DevParam && cd "$HomePath"
|
cd "$ReleasePath" && "./Packer" -path "$BinaryName" -path Updater -version $VersionForPacker $DevParam && cd "$HomePath"
|
||||||
echo "Packer done!"
|
echo "Packer done!"
|
||||||
|
|
||||||
if [ "$BetaVersion" != "0" ]; then
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
@ -146,6 +161,12 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
||||||
SetupFile="tbeta${BetaVersion}_${BetaSignature}.tar.xz"
|
SetupFile="tbeta${BetaVersion}_${BetaSignature}.tar.xz"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
SymbolsHash=`head -n 1 "$ReleasePath/$BinaryName.sym" | awk -F " " 'END {print $4}'`
|
||||||
|
echo "Copying $BinaryName.sym to $DropboxSymbolsPath/$BinaryName/$SymbolsHash"
|
||||||
|
mkdir -p "$DropboxSymbolsPath/$BinaryName/$SymbolsHash"
|
||||||
|
cp "$ReleasePath/$BinaryName.sym" "$DropboxSymbolsPath/$BinaryName/$SymbolsHash/"
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
if [ ! -d "$ReleasePath/deploy" ]; then
|
if [ ! -d "$ReleasePath/deploy" ]; then
|
||||||
mkdir "$ReleasePath/deploy"
|
mkdir "$ReleasePath/deploy"
|
||||||
fi
|
fi
|
||||||
|
@ -154,21 +175,25 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
|
||||||
mkdir "$ReleasePath/deploy/$AppVersionStrMajor"
|
mkdir "$ReleasePath/deploy/$AppVersionStrMajor"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Copying Telegram, Updater and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStrFull..";
|
echo "Copying $BinaryName, Updater and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStrFull..";
|
||||||
mkdir "$DeployPath"
|
mkdir "$DeployPath"
|
||||||
mkdir "$DeployPath/Telegram"
|
mkdir "$DeployPath/$BinaryName"
|
||||||
mv "$ReleasePath/Telegram" "$DeployPath/Telegram/"
|
mv "$ReleasePath/$BinaryName" "$DeployPath/$BinaryName/"
|
||||||
mv "$ReleasePath/Updater" "$DeployPath/Telegram/"
|
mv "$ReleasePath/Updater" "$DeployPath/$BinaryName/"
|
||||||
mv "$ReleasePath/$UpdateFile" "$DeployPath/"
|
mv "$ReleasePath/$UpdateFile" "$DeployPath/"
|
||||||
if [ "$BetaVersion" != "0" ]; then
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
mv "$ReleasePath/$BetaKeyFile" "$DeployPath/"
|
mv "$ReleasePath/$BetaKeyFile" "$DeployPath/"
|
||||||
fi
|
fi
|
||||||
cd "$DeployPath" && tar -cJvf "$SetupFile" "Telegram/" && cd "./../../../$HomePath"
|
cd "$DeployPath" && tar -cJvf "$SetupFile" "$BinaryName/" && cd "./../../../$HomePath"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
|
||||||
|
|
||||||
touch "./SourceFiles/telegram.qrc"
|
DropboxSymbolsPath="./../../../Dropbox/Telegram/symbols"
|
||||||
|
|
||||||
|
if [ "$FastParam" != "fast" ]; then
|
||||||
|
touch "./SourceFiles/telegram.qrc"
|
||||||
|
fi
|
||||||
xcodebuild -project Telegram.xcodeproj -alltargets -configuration Release build
|
xcodebuild -project Telegram.xcodeproj -alltargets -configuration Release build
|
||||||
|
|
||||||
if [ ! -d "$ReleasePath/$BinaryName.app" ]; then
|
if [ ! -d "$ReleasePath/$BinaryName.app" ]; then
|
||||||
|
@ -181,6 +206,28 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
||||||
|
echo "Removing Updater debug symbols.."
|
||||||
|
rm -rf "$ReleasePath/$BinaryName.app/Contents/Frameworks/Updater.dSYM"
|
||||||
|
echo "Done!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Dumping debug symbols.."
|
||||||
|
"./../../Libraries/breakpad/src/tools/mac/dump_syms/build/Release/dump_syms" "$ReleasePath/$BinaryName.app.dSYM" > "$ReleasePath/$BinaryName.sym" 2>/dev/null
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
|
echo "Stripping the executable.."
|
||||||
|
strip "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
|
echo "Signing the application.."
|
||||||
|
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
||||||
|
codesign --force --deep --sign "Developer ID Application: John Preston" "$ReleasePath/$BinaryName.app"
|
||||||
|
elif [ "$BuildTarget" == "macstore" ]; then
|
||||||
|
codesign --force --deep --sign "3rd Party Mac Developer Application: TELEGRAM MESSENGER LLP (6N38VWS5BX)" "$ReleasePath/$BinaryName.app" --entitlements "Telegram/Telegram Desktop.entitlements"
|
||||||
|
fi
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
AppUUID=`dwarfdump -u "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName" | awk -F " " '{print $2}'`
|
AppUUID=`dwarfdump -u "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName" | awk -F " " '{print $2}'`
|
||||||
DsymUUID=`dwarfdump -u "$ReleasePath/$BinaryName.app.dSYM" | awk -F " " '{print $2}'`
|
DsymUUID=`dwarfdump -u "$ReleasePath/$BinaryName.app.dSYM" | awk -F " " '{print $2}'`
|
||||||
if [ "$AppUUID" != "$DsymUUID" ]; then
|
if [ "$AppUUID" != "$DsymUUID" ]; then
|
||||||
|
@ -215,6 +262,12 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
SymbolsHash=`head -n 1 "$ReleasePath/$BinaryName.sym" | awk -F " " 'END {print $4}'`
|
||||||
|
echo "Copying $BinaryName.sym to $DropboxSymbolsPath/$BinaryName/$SymbolsHash"
|
||||||
|
mkdir -p "$DropboxSymbolsPath/$BinaryName/$SymbolsHash"
|
||||||
|
cp "$ReleasePath/$BinaryName.sym" "$DropboxSymbolsPath/$BinaryName/$SymbolsHash/"
|
||||||
|
echo "Done!"
|
||||||
|
|
||||||
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
||||||
if [ "$BetaVersion" == "0" ]; then
|
if [ "$BetaVersion" == "0" ]; then
|
||||||
cd "$ReleasePath"
|
cd "$ReleasePath"
|
||||||
|
@ -254,10 +307,10 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||||
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ]; then
|
||||||
echo "Copying $BinaryName.app and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStr..";
|
echo "Copying $BinaryName.app and $UpdateFile to deploy/$AppVersionStrMajor/$AppVersionStr..";
|
||||||
mkdir "$DeployPath"
|
mkdir "$DeployPath"
|
||||||
mkdir "$DeployPath/Telegram"
|
mkdir "$DeployPath/$BinaryName"
|
||||||
cp -r "$ReleasePath/$BinaryName.app" "$DeployPath/Telegram/"
|
cp -r "$ReleasePath/$BinaryName.app" "$DeployPath/$BinaryName/"
|
||||||
if [ "$BetaVersion" != "0" ]; then
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
cd "$DeployPath" && zip -r "$SetupFile" "Telegram" && mv "$SetupFile" "./../../../" && cd "./../../../$HomePath"
|
cd "$DeployPath" && zip -r "$SetupFile" "$BinaryName" && mv "$SetupFile" "./../../../" && cd "./../../../$HomePath"
|
||||||
mv "$ReleasePath/$BetaKeyFile" "$DeployPath/"
|
mv "$ReleasePath/$BetaKeyFile" "$DeployPath/"
|
||||||
fi
|
fi
|
||||||
mv "$ReleasePath/$BinaryName.app.dSYM" "$DeployPath/"
|
mv "$ReleasePath/$BinaryName.app.dSYM" "$DeployPath/"
|
||||||
|
@ -294,6 +347,7 @@ if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarg
|
||||||
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
|
rm "$ReleasePath/$BinaryName.app/Contents/MacOS/$BinaryName"
|
||||||
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
|
rm -rf "$ReleasePath/$BinaryName.app/Contents/_CodeSignature"
|
||||||
|
|
||||||
|
mkdir -p "$DropboxDeployPath"
|
||||||
cp -v "$DeployPath/$BinaryName.app" "$DropboxDeployPath/"
|
cp -v "$DeployPath/$BinaryName.app" "$DropboxDeployPath/"
|
||||||
cp -rv "$DeployPath/$BinaryName.app.dSYM" "$DropboxDeployPath/"
|
cp -rv "$DeployPath/$BinaryName.app.dSYM" "$DropboxDeployPath/"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -57,7 +57,11 @@ elif [ "$BuildTarget" == "mac" ]; then
|
||||||
echo "Deploying version $AppVersionStrFull for Windows.."
|
echo "Deploying version $AppVersionStrFull for Windows.."
|
||||||
else
|
else
|
||||||
DeployMac="1"
|
DeployMac="1"
|
||||||
DeployMac32="1"
|
if [ "$BetaVersion" != "0" ]; then
|
||||||
|
DeployMac32="0"
|
||||||
|
else
|
||||||
|
DeployMac32="1"
|
||||||
|
fi
|
||||||
DeployWin="1"
|
DeployWin="1"
|
||||||
echo "Deploying three versions of $AppVersionStrFull: for Windows, OS X 10.6 and 10.7 and OS X 10.8+.."
|
echo "Deploying three versions of $AppVersionStrFull: for Windows, OS X 10.6 and 10.7 and OS X 10.8+.."
|
||||||
fi
|
fi
|
||||||
|
@ -165,13 +169,7 @@ fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "$DropboxPath" ]; then
|
mkdir -p "$DropboxDeployPath"
|
||||||
mkdir "$DropboxPath"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d "$DropboxDeployPath" ]; then
|
|
||||||
mkdir "$DropboxDeployPath"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
#fi
|
#fi
|
||||||
|
|
||||||
|
@ -194,7 +192,6 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$Build
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$DeployMac" == "1" ]; then
|
if [ "$DeployMac" == "1" ]; then
|
||||||
cp -v "$DeployPath/$UpdateFile" "$DropboxDeployPath/"
|
|
||||||
cp -v "$DeployPath/$SetupFile" "$DropboxDeployPath/$DropboxSetupFile"
|
cp -v "$DeployPath/$SetupFile" "$DropboxDeployPath/$DropboxSetupFile"
|
||||||
if [ -d "$DropboxDeployPath/Telegram.app.dSYM" ]; then
|
if [ -d "$DropboxDeployPath/Telegram.app.dSYM" ]; then
|
||||||
rm -rf "$DropboxDeployPath/Telegram.app.dSYM"
|
rm -rf "$DropboxDeployPath/Telegram.app.dSYM"
|
||||||
|
@ -202,7 +199,6 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$Build
|
||||||
cp -rv "$DeployPath/Telegram.app.dSYM" "$DropboxDeployPath/"
|
cp -rv "$DeployPath/Telegram.app.dSYM" "$DropboxDeployPath/"
|
||||||
fi
|
fi
|
||||||
if [ "$DeployMac32" == "1" ]; then
|
if [ "$DeployMac32" == "1" ]; then
|
||||||
mv -v "$Mac32DeployPath/$Mac32UpdateFile" "$DropboxDeployPath/"
|
|
||||||
mv -v "$Mac32DeployPath/$Mac32SetupFile" "$DropboxDeployPath/$DropboxMac32SetupFile"
|
mv -v "$Mac32DeployPath/$Mac32SetupFile" "$DropboxDeployPath/$DropboxMac32SetupFile"
|
||||||
if [ -d "$DropboxDeployPath/Telegram32.app.dSYM" ]; then
|
if [ -d "$DropboxDeployPath/Telegram32.app.dSYM" ]; then
|
||||||
rm -rf "$DropboxDeployPath/Telegram32.app.dSYM"
|
rm -rf "$DropboxDeployPath/Telegram32.app.dSYM"
|
||||||
|
@ -213,7 +209,6 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$Build
|
||||||
mv -v "$WinDeployPath/Telegram.pdb" "$DropboxDeployPath/"
|
mv -v "$WinDeployPath/Telegram.pdb" "$DropboxDeployPath/"
|
||||||
mv -v "$WinDeployPath/Updater.exe" "$DropboxDeployPath/"
|
mv -v "$WinDeployPath/Updater.exe" "$DropboxDeployPath/"
|
||||||
mv -v "$WinDeployPath/Updater.pdb" "$DropboxDeployPath/"
|
mv -v "$WinDeployPath/Updater.pdb" "$DropboxDeployPath/"
|
||||||
mv -v "$WinDeployPath/$WinUpdateFile" "$DropboxDeployPath/"
|
|
||||||
if [ "$BetaVersion" == "0" ]; then
|
if [ "$BetaVersion" == "0" ]; then
|
||||||
mv -v "$WinDeployPath/$WinSetupFile" "$DropboxDeployPath/"
|
mv -v "$WinDeployPath/$WinSetupFile" "$DropboxDeployPath/"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -11,12 +11,7 @@ Replace () {
|
||||||
}
|
}
|
||||||
|
|
||||||
Replace '\-llzma' '\/usr\/lib\/x86_64\-linux\-gnu\/liblzma\.a'
|
Replace '\-llzma' '\/usr\/lib\/x86_64\-linux\-gnu\/liblzma\.a'
|
||||||
Replace '\-lz' '\/usr\/lib\/x86_64\-linux\-gnu\/libz\.a'
|
Replace '\-lXi' '\/usr\/lib\/x86_64\-linux\-gnu\/libXi\.a \/usr\/lib\/x86_64\-linux\-gnu\/libXext\.a'
|
||||||
Replace '\-lssl' '\/usr\/lib\/x86_64\-linux\-gnu\/libssl\.a'
|
|
||||||
Replace '\-lcrypto' '\/usr\/lib\/x86_64\-linux\-gnu\/libcrypto\.a'
|
|
||||||
Replace '\-lexif' '\/usr\/lib\/x86_64\-linux\-gnu\/libexif\.a'
|
|
||||||
Replace '\-lgobject\-2\.0' '\/usr\/lib\/x86_64\-linux\-gnu\/libgobject\-2\.0\.a \/usr\/lib\/x86_64\-linux\-gnu\/libffi\.a'
|
|
||||||
Replace '\-lXi' '\/usr\/lib\/x86_64\-linux\-gnu\/libXi\.a'
|
|
||||||
Replace '\-lSM' '\/usr\/lib\/x86_64\-linux\-gnu\/libSM\.a'
|
Replace '\-lSM' '\/usr\/lib\/x86_64\-linux\-gnu\/libSM\.a'
|
||||||
Replace '\-lICE' '\/usr\/lib\/x86_64\-linux\-gnu\/libICE\.a'
|
Replace '\-lICE' '\/usr\/lib\/x86_64\-linux\-gnu\/libICE\.a'
|
||||||
Replace '\-lfontconfig' '\/usr\/lib\/x86_64\-linux\-gnu\/libfontconfig\.a \/usr\/lib\/x86_64\-linux\-gnu\/libexpat\.a'
|
Replace '\-lfontconfig' '\/usr\/lib\/x86_64\-linux\-gnu\/libfontconfig\.a \/usr\/lib\/x86_64\-linux\-gnu\/libexpat\.a'
|
||||||
|
@ -30,3 +25,4 @@ Replace '\-lswresample' '\/usr\/local\/lib\/libswresample\.a'
|
||||||
Replace '\-lswscale' '\/usr\/local\/lib\/libswscale\.a'
|
Replace '\-lswscale' '\/usr\/local\/lib\/libswscale\.a'
|
||||||
Replace '\-lavutil' '\/usr\/local\/lib\/libavutil\.a'
|
Replace '\-lavutil' '\/usr\/local\/lib\/libavutil\.a'
|
||||||
Replace '\-lva' '\/usr\/local\/lib\/libva\.a'
|
Replace '\-lva' '\/usr\/local\/lib\/libva\.a'
|
||||||
|
Replace '\-lQt5Network' '\/usr\/local\/Qt-5.5.1\/lib\/libQt5Network.a \/usr\/local\/ssl\/lib\/libssl.a \/usr\/local\/ssl\/lib\/libcrypto.a'
|
||||||
|
|
|
@ -11,12 +11,7 @@ Replace () {
|
||||||
}
|
}
|
||||||
|
|
||||||
Replace '\-llzma' '\/usr\/lib\/i386\-linux\-gnu\/liblzma\.a'
|
Replace '\-llzma' '\/usr\/lib\/i386\-linux\-gnu\/liblzma\.a'
|
||||||
Replace '\-lz' '\/usr\/lib\/i386\-linux\-gnu\/libz\.a'
|
Replace '\-lXi' '\/usr\/lib\/i386\-linux\-gnu\/libXi\.a \/usr\/lib\/i386\-linux\-gnu\/libXext\.a'
|
||||||
Replace '\-lssl' '\/usr\/lib\/i386\-linux\-gnu\/libssl\.a'
|
|
||||||
Replace '\-lcrypto' '\/usr\/lib\/i386\-linux\-gnu\/libcrypto\.a'
|
|
||||||
Replace '\-lexif' '\/usr\/lib\/i386\-linux\-gnu\/libexif\.a'
|
|
||||||
Replace '\-lgobject\-2\.0' '\/usr\/lib\/i386\-linux\-gnu\/libgobject\-2\.0\.a \/usr\/lib\/i386\-linux\-gnu\/libffi\.a'
|
|
||||||
Replace '\-lXi' '\/usr\/lib\/i386\-linux\-gnu\/libXi\.a'
|
|
||||||
Replace '\-lSM' '\/usr\/lib\/i386\-linux\-gnu\/libSM\.a'
|
Replace '\-lSM' '\/usr\/lib\/i386\-linux\-gnu\/libSM\.a'
|
||||||
Replace '\-lICE' '\/usr\/lib\/i386\-linux\-gnu\/libICE\.a'
|
Replace '\-lICE' '\/usr\/lib\/i386\-linux\-gnu\/libICE\.a'
|
||||||
Replace '\-lfontconfig' '\/usr\/lib\/i386\-linux\-gnu\/libfontconfig\.a \/usr\/lib\/i386\-linux\-gnu\/libexpat\.a'
|
Replace '\-lfontconfig' '\/usr\/lib\/i386\-linux\-gnu\/libfontconfig\.a \/usr\/lib\/i386\-linux\-gnu\/libexpat\.a'
|
||||||
|
@ -30,3 +25,4 @@ Replace '\-lswresample' '\/usr\/local\/lib\/libswresample\.a'
|
||||||
Replace '\-lswscale' '\/usr\/local\/lib\/libswscale\.a'
|
Replace '\-lswscale' '\/usr\/local\/lib\/libswscale\.a'
|
||||||
Replace '\-lavutil' '\/usr\/local\/lib\/libavutil\.a'
|
Replace '\-lavutil' '\/usr\/local\/lib\/libavutil\.a'
|
||||||
Replace '\-lva' '\/usr\/local\/lib\/libva\.a'
|
Replace '\-lva' '\/usr\/local\/lib\/libva\.a'
|
||||||
|
Replace '\-lQt5Network' '\/usr\/local\/Qt-5.5.1\/lib\/libQt5Network.a \/usr\/local\/ssl\/lib\/libssl.a \/usr\/local\/ssl\/lib\/libcrypto.a'
|
||||||
|
|
|
@ -12,7 +12,7 @@ CONFIG(release, debug|release) {
|
||||||
DESTDIR = ./../ReleaseLang
|
DESTDIR = ./../ReleaseLang
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG += plugin static
|
CONFIG += plugin static c++11
|
||||||
|
|
||||||
macx {
|
macx {
|
||||||
QMAKE_INFO_PLIST = ./SourceFiles/_other/Lang.plist
|
QMAKE_INFO_PLIST = ./SourceFiles/_other/Lang.plist
|
||||||
|
|
|
@ -12,7 +12,7 @@ CONFIG(release, debug|release) {
|
||||||
DESTDIR = ./../ReleaseStyle
|
DESTDIR = ./../ReleaseStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG += plugin static
|
CONFIG += plugin static c++11
|
||||||
|
|
||||||
macx {
|
macx {
|
||||||
QMAKE_INFO_PLIST = ./SourceFiles/_other/Style.plist
|
QMAKE_INFO_PLIST = ./SourceFiles/_other/Style.plist
|
||||||
|
|
1
Telegram/Resources/LangList
Normal file
1
Telegram/Resources/LangList
Normal file
|
@ -0,0 +1 @@
|
||||||
|
de,es,it,ko,nl,pt_BR
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
"lng_language_name" = "English";
|
"lng_language_name" = "English";
|
||||||
"lng_switch_to_this" = "Switch to English";
|
"lng_switch_to_this" = "Switch to English";
|
||||||
|
@ -86,8 +86,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_cancel" = "Cancel";
|
"lng_cancel" = "Cancel";
|
||||||
"lng_continue" = "Continue";
|
"lng_continue" = "Continue";
|
||||||
"lng_close" = "Close";
|
"lng_close" = "Close";
|
||||||
"lng_connecting" = "Connecting..";
|
"lng_connecting" = "Connecting...";
|
||||||
"lng_reconnecting" = "Reconnect {count:now|in # s|in # s}..";
|
"lng_reconnecting" = "Reconnect {count:now|in # s|in # s}...";
|
||||||
"lng_reconnecting_try_now" = "Try now";
|
"lng_reconnecting_try_now" = "Try now";
|
||||||
|
|
||||||
"lng_status_service_notifications" = "service notifications";
|
"lng_status_service_notifications" = "service notifications";
|
||||||
|
@ -108,7 +108,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_status_lastseen_date" = "last seen {date}";
|
"lng_status_lastseen_date" = "last seen {date}";
|
||||||
"lng_status_lastseen_date_time" = "last seen {date} at {time}";
|
"lng_status_lastseen_date_time" = "last seen {date} at {time}";
|
||||||
"lng_status_online" = "online";
|
"lng_status_online" = "online";
|
||||||
"lng_status_connecting" = "connecting..";
|
"lng_status_connecting" = "connecting...";
|
||||||
|
|
||||||
"lng_chat_status_unaccessible" = "group is unaccessible";
|
"lng_chat_status_unaccessible" = "group is unaccessible";
|
||||||
"lng_chat_status_members" = "{count:no members|# member|# members}";
|
"lng_chat_status_members" = "{count:no members|# member|# members}";
|
||||||
|
@ -123,8 +123,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_server_error" = "Internal server error.";
|
"lng_server_error" = "Internal server error.";
|
||||||
"lng_flood_error" = "Too many tries. Please try again later.";
|
"lng_flood_error" = "Too many tries. Please try again later.";
|
||||||
"lng_gif_error" = "An error has occured while reading GIF animation :(";
|
"lng_gif_error" = "An error has occured while reading GIF animation :(";
|
||||||
|
"lng_edit_error" = "You cannot edit this message";
|
||||||
|
"lng_edit_deleted" = "This message was deleted";
|
||||||
|
"lng_edit_too_long" = "Your message text is too long";
|
||||||
|
"lng_edit_message" = "Edit message";
|
||||||
|
"lng_edit_message_text" = "New message text...";
|
||||||
"lng_deleted" = "Unknown";
|
"lng_deleted" = "Unknown";
|
||||||
"lng_deleted_message" = "Deleted message";
|
"lng_deleted_message" = "Deleted message";
|
||||||
|
"lng_pinned_message" = "Pinned message";
|
||||||
|
"lng_pinned_unpin_sure" = "Would you like to unpin this message?";
|
||||||
|
"lng_pinned_pin_sure" = "Would you like to pin this message?";
|
||||||
|
"lng_pinned_pin" = "Pin";
|
||||||
|
"lng_pinned_unpin" = "Unpin";
|
||||||
|
"lng_pinned_notify" = "Notify all members";
|
||||||
|
|
||||||
"lng_intro" = "Welcome to the official [a href=\"https://telegram.org/\"]Telegram[/a] desktop app.\nIt's [b]fast[/b] and [b]secure[/b].";
|
"lng_intro" = "Welcome to the official [a href=\"https://telegram.org/\"]Telegram[/a] desktop app.\nIt's [b]fast[/b] and [b]secure[/b].";
|
||||||
"lng_start_msgs" = "START MESSAGING";
|
"lng_start_msgs" = "START MESSAGING";
|
||||||
|
@ -151,7 +162,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_code_telegram" = "Please enter the code you've just\nreceived in your previous [b]Telegram[/b] app.";
|
"lng_code_telegram" = "Please enter the code you've just\nreceived in your previous [b]Telegram[/b] app.";
|
||||||
"lng_code_no_telegram" = "Send code via SMS";
|
"lng_code_no_telegram" = "Send code via SMS";
|
||||||
"lng_code_call" = "Telegram will dial your number in {minutes}:{seconds}";
|
"lng_code_call" = "Telegram will dial your number in {minutes}:{seconds}";
|
||||||
"lng_code_calling" = "Requesting a call from Telegram..";
|
"lng_code_calling" = "Requesting a call from Telegram...";
|
||||||
"lng_code_called" = "Telegram dialed your number";
|
"lng_code_called" = "Telegram dialed your number";
|
||||||
|
|
||||||
"lng_bad_phone" = "Invalid phone number. Please try again.";
|
"lng_bad_phone" = "Invalid phone number. Please try again.";
|
||||||
|
@ -190,7 +201,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_dlg_new_channel_name" = "Channel name";
|
"lng_dlg_new_channel_name" = "Channel name";
|
||||||
"lng_no_contacts" = "You have no contacts";
|
"lng_no_contacts" = "You have no contacts";
|
||||||
"lng_no_chats" = "Your chats will be here";
|
"lng_no_chats" = "Your chats will be here";
|
||||||
"lng_contacts_loading" = "Loading..";
|
"lng_contacts_loading" = "Loading...";
|
||||||
"lng_contacts_not_found" = "No contacts found";
|
"lng_contacts_not_found" = "No contacts found";
|
||||||
"lng_dlg_search_chat" = "Search in this chat";
|
"lng_dlg_search_chat" = "Search in this chat";
|
||||||
"lng_dlg_search_channel" = "Search in this channel";
|
"lng_dlg_search_channel" = "Search in this channel";
|
||||||
|
@ -199,7 +210,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_settings_save" = "Save";
|
"lng_settings_save" = "Save";
|
||||||
"lng_settings_upload" = "Set Profile Photo";
|
"lng_settings_upload" = "Set Profile Photo";
|
||||||
"lng_settings_crop_profile" = "Select a square area for your profile photo";
|
"lng_settings_crop_profile" = "Select a square area for your profile photo";
|
||||||
"lng_settings_uploading_photo" = "Uploading photo..";
|
"lng_settings_uploading_photo" = "Uploading photo...";
|
||||||
|
|
||||||
"lng_username_title" = "Username";
|
"lng_username_title" = "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_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.";
|
||||||
|
@ -236,9 +247,9 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_settings_auto_update" = "Update automatically";
|
"lng_settings_auto_update" = "Update automatically";
|
||||||
"lng_settings_current_version" = "Version {version}";
|
"lng_settings_current_version" = "Version {version}";
|
||||||
"lng_settings_check_now" = "Check for updates";
|
"lng_settings_check_now" = "Check for updates";
|
||||||
"lng_settings_update_checking" = "Checking for updates..";
|
"lng_settings_update_checking" = "Checking for updates...";
|
||||||
"lng_settings_latest_installed" = "Latest version is installed";
|
"lng_settings_latest_installed" = "Latest version is installed";
|
||||||
"lng_settings_downloading" = "Downloading update {ready} / {total} MB..";
|
"lng_settings_downloading" = "Downloading update {ready} / {total} MB...";
|
||||||
"lng_settings_update_ready" = "New version is ready";
|
"lng_settings_update_ready" = "New version is ready";
|
||||||
"lng_settings_update_now" = "Restart Now";
|
"lng_settings_update_now" = "Restart Now";
|
||||||
"lng_settings_update_fail" = "Update check failed :(";
|
"lng_settings_update_fail" = "Update check failed :(";
|
||||||
|
@ -262,6 +273,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_settings_bg_from_gallery" = "Choose from gallery";
|
"lng_settings_bg_from_gallery" = "Choose from gallery";
|
||||||
"lng_settings_bg_from_file" = "Choose from file";
|
"lng_settings_bg_from_file" = "Choose from file";
|
||||||
"lng_settings_bg_tile" = "Tile background";
|
"lng_settings_bg_tile" = "Tile background";
|
||||||
|
"lng_settings_adaptive_wide" = "Adaptive layout for wide screens";
|
||||||
|
|
||||||
"lng_backgrounds_header" = "Choose your new chat background";
|
"lng_backgrounds_header" = "Choose your new chat background";
|
||||||
|
|
||||||
|
@ -279,7 +291,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_download_path_failed" = "File download could not be started. It could happen because of a bad download location.\n\nYou can change download path in Settings.";
|
"lng_download_path_failed" = "File download could not be started. It could happen because of a bad download location.\n\nYou can change download path in Settings.";
|
||||||
"lng_download_path_settings" = "Settings";
|
"lng_download_path_settings" = "Settings";
|
||||||
"lng_download_finish_failed" = "File download could not be finished.\n\nWould you like to try again?";
|
"lng_download_finish_failed" = "File download could not be finished.\n\nWould you like to try again?";
|
||||||
"lng_download_path_clearing" = "Clearing..";
|
"lng_download_path_clearing" = "Clearing...";
|
||||||
"lng_download_path_cleared" = "Cleared!";
|
"lng_download_path_cleared" = "Cleared!";
|
||||||
"lng_download_path_clear_failed" = "Clear failed :(";
|
"lng_download_path_clear_failed" = "Clear failed :(";
|
||||||
|
|
||||||
|
@ -288,7 +300,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_settings_images_cached" = "{count:_not_used_|# image|# images}, {size}";
|
"lng_settings_images_cached" = "{count:_not_used_|# image|# images}, {size}";
|
||||||
"lng_settings_audios_cached" = "{count:_not_used_|# voice message|# voice messages}, {size}";
|
"lng_settings_audios_cached" = "{count:_not_used_|# voice message|# voice messages}, {size}";
|
||||||
"lng_local_storage_clear" = "Clear all";
|
"lng_local_storage_clear" = "Clear all";
|
||||||
"lng_local_storage_clearing" = "Clearing..";
|
"lng_local_storage_clearing" = "Clearing...";
|
||||||
"lng_local_storage_cleared" = "Cleared!";
|
"lng_local_storage_cleared" = "Cleared!";
|
||||||
"lng_local_storage_clear_failed" = "Clear failed :(";
|
"lng_local_storage_clear_failed" = "Clear failed :(";
|
||||||
|
|
||||||
|
@ -319,7 +331,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_passcode_logout" = "Log out";
|
"lng_passcode_logout" = "Log out";
|
||||||
"lng_passcode_need_unblock" = "You need to unlock me first.";
|
"lng_passcode_need_unblock" = "You need to unlock me first.";
|
||||||
|
|
||||||
"lng_cloud_password_waiting" = "Confirmation link sent to {email}..";
|
"lng_cloud_password_waiting" = "Confirmation link sent to {email}...";
|
||||||
"lng_cloud_password_change" = "Change cloud password";
|
"lng_cloud_password_change" = "Change cloud password";
|
||||||
"lng_cloud_password_create" = "Cloud password";
|
"lng_cloud_password_create" = "Cloud password";
|
||||||
"lng_cloud_password_remove" = "Remove cloud password";
|
"lng_cloud_password_remove" = "Remove cloud password";
|
||||||
|
@ -346,9 +358,9 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_cloud_password_is_same" = "Password was not changed";
|
"lng_cloud_password_is_same" = "Password was not changed";
|
||||||
|
|
||||||
"lng_connection_type" = "Connection type:";
|
"lng_connection_type" = "Connection type:";
|
||||||
"lng_connection_auto_connecting" = "Default (connecting..)";
|
"lng_connection_auto_connecting" = "Default (connecting...)";
|
||||||
"lng_connection_auto" = "Default ({transport} used)";
|
"lng_connection_auto" = "Default ({transport} used)";
|
||||||
"lng_connection_proxy_connecting" = "Connecting through proxy..";
|
"lng_connection_proxy_connecting" = "Connecting through proxy...";
|
||||||
"lng_connection_proxy" = "{transport} with proxy";
|
"lng_connection_proxy" = "{transport} with proxy";
|
||||||
"lng_connection_header" = "Connection type";
|
"lng_connection_header" = "Connection type";
|
||||||
"lng_connection_auto_rb" = "Auto (TCP if available or HTTP)";
|
"lng_connection_auto_rb" = "Auto (TCP if available or HTTP)";
|
||||||
|
@ -384,7 +396,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_sessions_other_desc" = "You can log in to Telegram from other mobile, tablet and desktop devices, using the same phone number. All your data will be instantly synchronized.";
|
"lng_sessions_other_desc" = "You can log in to Telegram from other mobile, tablet and desktop devices, using the same phone number. All your data will be instantly synchronized.";
|
||||||
"lng_sessions_terminate_all" = "Terminate all other sessions";
|
"lng_sessions_terminate_all" = "Terminate all other sessions";
|
||||||
|
|
||||||
"lng_preview_loading" = "Getting Link Info..";
|
"lng_preview_loading" = "Getting Link Info...";
|
||||||
|
|
||||||
"lng_profile_chat_unaccessible" = "Group is unaccessible";
|
"lng_profile_chat_unaccessible" = "Group is unaccessible";
|
||||||
"lng_topbar_info" = "Info";
|
"lng_topbar_info" = "Info";
|
||||||
|
@ -423,10 +435,11 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_add_participant" = "Add Members";
|
"lng_profile_add_participant" = "Add Members";
|
||||||
"lng_profile_delete_and_exit" = "Leave";
|
"lng_profile_delete_and_exit" = "Leave";
|
||||||
"lng_profile_kick" = "Remove";
|
"lng_profile_kick" = "Remove";
|
||||||
|
"lng_profile_admin" = "admin";
|
||||||
"lng_profile_sure_kick" = "Remove {user} from the group?";
|
"lng_profile_sure_kick" = "Remove {user} from the group?";
|
||||||
"lng_profile_sure_kick_channel" = "Remove {user} from the channel?";
|
"lng_profile_sure_kick_channel" = "Remove {user} from the channel?";
|
||||||
"lng_profile_sure_kick_admin" = "Remove {user} from administrators?";
|
"lng_profile_sure_kick_admin" = "Remove {user} from administrators?";
|
||||||
"lng_profile_loading" = "Loading..";
|
"lng_profile_loading" = "Loading...";
|
||||||
"lng_profile_shared_media" = "Shared media";
|
"lng_profile_shared_media" = "Shared media";
|
||||||
"lng_profile_no_media" = "No media in this conversation.";
|
"lng_profile_no_media" = "No media in this conversation.";
|
||||||
"lng_profile_photos" = "{count:_not_used_|# photo|# photos} »";
|
"lng_profile_photos" = "{count:_not_used_|# photo|# photos} »";
|
||||||
|
@ -442,6 +455,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links} »";
|
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links} »";
|
||||||
"lng_profile_shared_links_header" = "Shared links overview";
|
"lng_profile_shared_links_header" = "Shared links overview";
|
||||||
"lng_profile_copy_phone" = "Copy phone number";
|
"lng_profile_copy_phone" = "Copy phone number";
|
||||||
|
"lng_profile_copy_fullname" = "Copy name";
|
||||||
|
|
||||||
"lng_channel_add_admins" = "New administrator";
|
"lng_channel_add_admins" = "New administrator";
|
||||||
"lng_channel_add_members" = "Add members";
|
"lng_channel_add_members" = "Add members";
|
||||||
|
@ -463,13 +477,17 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "Next";
|
"lng_create_group_next" = "Next";
|
||||||
"lng_create_group_create" = "Create";
|
"lng_create_group_create" = "Create";
|
||||||
"lng_create_group_title" = "New Group";
|
"lng_create_group_title" = "New Group";
|
||||||
"lng_create_group_about" = "Groups are ideal for smaller communities,\nthey can have up to {count:_not_used|# member|# members}";
|
"lng_create_group_about" = "Groups are ideal for limited communities,\nthey can have up to {count:_not_used|# member|# members}";
|
||||||
"lng_create_channel_title" = "New Channel";
|
"lng_create_channel_title" = "New Channel";
|
||||||
"lng_create_channel_about" = "Channels are a tool for broadcasting your messages to unlimited audiences";
|
"lng_create_channel_about" = "Channels are a tool for broadcasting your messages to unlimited audiences";
|
||||||
"lng_create_public_channel_title" = "Public Channel";
|
"lng_create_public_channel_title" = "Public Channel";
|
||||||
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
||||||
"lng_create_private_channel_title" = "Private Channel";
|
"lng_create_private_channel_title" = "Private Channel";
|
||||||
"lng_create_private_channel_about" = "Only people with a special invite link may join";
|
"lng_create_private_channel_about" = "Only people with a special invite link may join";
|
||||||
|
"lng_create_public_group_title" = "Public Group";
|
||||||
|
"lng_create_public_group_about" = "Anyone can find the group in search and join, chat history is available to everybody";
|
||||||
|
"lng_create_private_group_title" = "Private Group";
|
||||||
|
"lng_create_private_group_about" = "People can only join if they were invited or have an invite link";
|
||||||
"lng_create_channel_comments" = "Enable Comments";
|
"lng_create_channel_comments" = "Enable Comments";
|
||||||
"lng_create_channel_comments_about" = "If you enable comments, members will be able to discuss your posts in the channel";
|
"lng_create_channel_comments_about" = "If you enable comments, members will be able to discuss your posts in the channel";
|
||||||
"lng_create_group_skip" = "Skip";
|
"lng_create_group_skip" = "Skip";
|
||||||
|
@ -498,7 +516,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_sure_delete_group" = "Are you sure, you want to delete this group? All members will be removed and all messages will be lost.";
|
"lng_sure_delete_group" = "Are you sure, you want to delete this group? All members will be removed and all messages will be lost.";
|
||||||
|
|
||||||
"lng_message_empty" = "Empty Message";
|
"lng_message_empty" = "Empty Message";
|
||||||
"lng_media_unsupported" = "Media Unsupported";
|
"lng_message_unsupported" = "This message is not supported by your version of Telegram Desktop. Please update to the last version in Settings or install it from {link}";
|
||||||
|
|
||||||
"lng_action_add_user" = "{from} added {user}";
|
"lng_action_add_user" = "{from} added {user}";
|
||||||
"lng_action_add_users_many" = "{from} added {users}";
|
"lng_action_add_users_many" = "{from} added {users}";
|
||||||
|
@ -522,6 +540,17 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} created group «{title}»";
|
"lng_action_created_chat" = "{from} created group «{title}»";
|
||||||
"lng_action_created_channel" = "Channel «{title}» created";
|
"lng_action_created_channel" = "Channel «{title}» created";
|
||||||
"lng_action_group_migrate" = "The group was upgraded to a supergroup";
|
"lng_action_group_migrate" = "The group was upgraded to a supergroup";
|
||||||
|
"lng_action_pinned_message" = "{from} pinned «{text}»";
|
||||||
|
"lng_action_pinned_media" = "{from} pinned {media}";
|
||||||
|
"lng_action_pinned_media_photo" = "a photo";
|
||||||
|
"lng_action_pinned_media_video" = "a video file";
|
||||||
|
"lng_action_pinned_media_audio" = "an audio file";
|
||||||
|
"lng_action_pinned_media_voice" = "a voice message";
|
||||||
|
"lng_action_pinned_media_file" = "a file";
|
||||||
|
"lng_action_pinned_media_gif" = "a GIF animation";
|
||||||
|
"lng_action_pinned_media_contact" = "a contact information";
|
||||||
|
"lng_action_pinned_media_location" = "a location mark";
|
||||||
|
"lng_action_pinned_media_sticker" = "a sticker";
|
||||||
|
|
||||||
"lng_profile_migrate_reached" = "{count:_not_used_|# member|# members} limit reached";
|
"lng_profile_migrate_reached" = "{count:_not_used_|# member|# members} limit reached";
|
||||||
"lng_profile_migrate_about" = "If you'd like to go over this limit, you can upgrade your group to a supergroup. In supergroups:";
|
"lng_profile_migrate_about" = "If you'd like to go over this limit, you can upgrade your group to a supergroup. In supergroups:";
|
||||||
|
@ -531,6 +560,16 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_migrate_feature4" = "— Notifications are muted by default";
|
"lng_profile_migrate_feature4" = "— Notifications are muted by default";
|
||||||
"lng_profile_migrate_button" = "Upgrade to supergroup";
|
"lng_profile_migrate_button" = "Upgrade to supergroup";
|
||||||
"lng_profile_migrate_sure" = "Are you sure you want to upgrade this group to supergroup? This action cannot be undone.";
|
"lng_profile_migrate_sure" = "Are you sure you want to upgrade this group to supergroup? This action cannot be undone.";
|
||||||
|
"lng_profile_convert_button" = "Convert to supergroup";
|
||||||
|
"lng_profile_convert_title" = "Convert to supergroup";
|
||||||
|
"lng_profile_convert_about" = "In supergroups:";
|
||||||
|
"lng_profile_convert_feature1" = "— New members see the full message history";
|
||||||
|
"lng_profile_convert_feature2" = "— Messages are deleted for all members";
|
||||||
|
"lng_profile_convert_feature3" = "— Members can edit their own messages";
|
||||||
|
"lng_profile_convert_feature4" = "— Creator can set a public link for the group";
|
||||||
|
"lng_profile_convert_warning" = "{bold_start}Note:{bold_end} This action can not be undone";
|
||||||
|
"lng_profile_convert_confirm" = "Convert";
|
||||||
|
"lng_profile_add_more_after_upgrade" = "You will be able to add up to {count:_not_used_|# member|# members} after you upgrade your group to a supergroup.";
|
||||||
|
|
||||||
"lng_channel_comments_count" = "{count:_not_used_|# comment|# comments}";
|
"lng_channel_comments_count" = "{count:_not_used_|# comment|# comments}";
|
||||||
"lng_channel_hide_comments" = "Hide comments";
|
"lng_channel_hide_comments" = "Hide comments";
|
||||||
|
@ -555,9 +594,18 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_channel_public_link_copied" = "Link copied to clipboard.";
|
"lng_channel_public_link_copied" = "Link copied to clipboard.";
|
||||||
|
|
||||||
"lng_forwarded_from" = "Forwarded from";
|
"lng_forwarded" = "Forwarded from {user}";
|
||||||
|
"lng_forwarded_channel" = "Forwarded from {channel}";
|
||||||
|
"lng_forwarded_via" = "Forwarded from {user} via {inline_bot}";
|
||||||
|
"lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}";
|
||||||
|
"lng_forwarded_signed" = "{channel} ({user})";
|
||||||
"lng_in_reply_to" = "In reply to";
|
"lng_in_reply_to" = "In reply to";
|
||||||
|
|
||||||
|
"lng_bot_share_location_unavailable" = "Sorry, the location sharing is currently unavailable in Telegram Desktop.";
|
||||||
|
"lng_bot_inline_geo_unavailable" = "Sorry, this bot requires location sharing.\nIt is not unavailable in Telegram Desktop.";
|
||||||
|
"lng_bot_share_phone" = "Share Phone Number?";
|
||||||
|
"lng_bot_share_phone_confirm" = "Share";
|
||||||
|
|
||||||
"lng_attach_failed" = "Failed";
|
"lng_attach_failed" = "Failed";
|
||||||
"lng_attach_file" = "File";
|
"lng_attach_file" = "File";
|
||||||
"lng_attach_photo" = "Photo";
|
"lng_attach_photo" = "Photo";
|
||||||
|
@ -600,6 +648,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_saved_gifs" = "Saved GIFs";
|
"lng_saved_gifs" = "Saved GIFs";
|
||||||
"lng_inline_bot_results" = "Results from {inline_bot}";
|
"lng_inline_bot_results" = "Results from {inline_bot}";
|
||||||
"lng_inline_bot_no_results" = "No results";
|
"lng_inline_bot_no_results" = "No results";
|
||||||
|
"lng_inline_bot_via" = "via {inline_bot}";
|
||||||
|
|
||||||
"lng_box_remove" = "Remove";
|
"lng_box_remove" = "Remove";
|
||||||
|
|
||||||
|
@ -616,16 +665,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_stickers_remove" = "Delete";
|
"lng_stickers_remove" = "Delete";
|
||||||
"lng_stickers_return" = "Undo";
|
"lng_stickers_return" = "Undo";
|
||||||
"lng_stickers_restore" = "Restore";
|
"lng_stickers_restore" = "Restore";
|
||||||
"lng_stickers_count" = "{count:Loading..|# sticker|# stickers}";
|
"lng_stickers_count" = "{count:Loading...|# sticker|# stickers}";
|
||||||
|
|
||||||
"lng_in_dlg_photo" = "Photo";
|
"lng_in_dlg_photo" = "Photo";
|
||||||
"lng_in_dlg_video" = "Video";
|
"lng_in_dlg_video" = "Video file";
|
||||||
|
"lng_in_dlg_audio_file" = "Audio file";
|
||||||
"lng_in_dlg_contact" = "Contact";
|
"lng_in_dlg_contact" = "Contact";
|
||||||
"lng_in_dlg_audio" = "Audio";
|
"lng_in_dlg_audio" = "Voice message";
|
||||||
"lng_in_dlg_file" = "File";
|
"lng_in_dlg_file" = "File";
|
||||||
"lng_in_dlg_sticker" = "Sticker";
|
"lng_in_dlg_sticker" = "Sticker";
|
||||||
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
||||||
|
|
||||||
|
"lng_ban_user" = "Ban User";
|
||||||
|
"lng_delete_all_from" = "Delete all from this user";
|
||||||
"lng_report_spam" = "Report Spam";
|
"lng_report_spam" = "Report Spam";
|
||||||
"lng_report_spam_hide" = "Hide";
|
"lng_report_spam_hide" = "Hide";
|
||||||
"lng_report_spam_thanks" = "Thank you for your report!";
|
"lng_report_spam_thanks" = "Thank you for your report!";
|
||||||
|
@ -633,16 +685,23 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_report_spam_sure_group" = "Are you sure you want to report spam in this group?";
|
"lng_report_spam_sure_group" = "Are you sure you want to report spam in this group?";
|
||||||
"lng_report_spam_sure_channel" = "Are you sure you want to report spam in this channel?";
|
"lng_report_spam_sure_channel" = "Are you sure you want to report spam in this channel?";
|
||||||
"lng_report_spam_ok" = "Report";
|
"lng_report_spam_ok" = "Report";
|
||||||
"lng_cant_send_to_not_contact" = "Sorry, you can only send messages to\nmutual contacts at the moment. {more_info}";
|
"lng_cant_send_to_not_contact" = "Sorry, you can only send messages to\nmutual contacts at the moment.\n{more_info}";
|
||||||
"lng_cant_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment. {more_info}";
|
"lng_cant_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment.\n{more_info}";
|
||||||
"lng_cant_invite_not_contact_channel" = "Sorry, you can only add mutual contacts\nto channels at the moment. {more_info}";
|
"lng_cant_invite_not_contact_channel" = "Sorry, you can only add mutual contacts\nto channels at the moment.\n{more_info}";
|
||||||
"lng_cant_more_info" = "More info »";
|
"lng_cant_more_info" = "More info »";
|
||||||
|
"lng_cant_invite_banned" = "Sorry, only admin can add this user.";
|
||||||
|
"lng_cant_invite_privacy" = "Sorry, you cannot add this user to groups because of the privacy settings.";
|
||||||
|
"lng_cant_invite_privacy_channel" = "Sorry, you cannot add this user to channels because of the privacy settings.";
|
||||||
|
"lng_cant_do_this" = "Sorry, this action is unavailable.";
|
||||||
|
|
||||||
"lng_send_button" = "Send";
|
"lng_send_button" = "Send";
|
||||||
"lng_message_ph" = "Write a message..";
|
"lng_message_ph" = "Write a message...";
|
||||||
"lng_comment_ph" = "Write a comment..";
|
"lng_comment_ph" = "Write a comment...";
|
||||||
"lng_broadcast_ph" = "Broadcast a message..";
|
"lng_broadcast_ph" = "Broadcast a message...";
|
||||||
|
"lng_broadcast_silent_ph" = "Silent broadcast...";
|
||||||
"lng_record_cancel" = "Release outside this field to cancel";
|
"lng_record_cancel" = "Release outside this field to cancel";
|
||||||
|
"lng_will_be_notified" = "Members will be notified when you post";
|
||||||
|
"lng_wont_be_notified" = "Members will not be notified when you post";
|
||||||
"lng_empty_history" = "";
|
"lng_empty_history" = "";
|
||||||
"lng_willbe_history" = "Please select a chat to start messaging";
|
"lng_willbe_history" = "Please select a chat to start messaging";
|
||||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||||
|
@ -667,28 +726,29 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_user_typing" = "{user} is typing";
|
"lng_user_typing" = "{user} is typing";
|
||||||
"lng_users_typing" = "{user} and {second_user} are typing";
|
"lng_users_typing" = "{user} and {second_user} are typing";
|
||||||
"lng_many_typing" = "{count:_not_used_|# is|# are} typing";
|
"lng_many_typing" = "{count:_not_used_|# is|# are} typing";
|
||||||
"lng_send_action_record_video" = "recording video";
|
"lng_send_action_record_video" = "recording a video";
|
||||||
"lng_user_action_record_video" = "{user} is recording video";
|
"lng_user_action_record_video" = "{user} is recording a video";
|
||||||
"lng_send_action_upload_video" = "sending video";
|
"lng_send_action_upload_video" = "sending a video";
|
||||||
"lng_user_action_upload_video" = "{user} is sending video";
|
"lng_user_action_upload_video" = "{user} is sending a video";
|
||||||
"lng_send_action_record_audio" = "recording audio";
|
"lng_send_action_record_audio" = "recording a voice message";
|
||||||
"lng_user_action_record_audio" = "{user} is recording audio";
|
"lng_user_action_record_audio" = "{user} is recording a voice message";
|
||||||
"lng_send_action_upload_audio" = "sending audio";
|
"lng_send_action_upload_audio" = "sending a voice message";
|
||||||
"lng_user_action_upload_audio" = "{user} is sending audio";
|
"lng_user_action_upload_audio" = "{user} is sending a voice message";
|
||||||
"lng_send_action_upload_photo" = "sending photo";
|
"lng_send_action_upload_photo" = "sending a photo";
|
||||||
"lng_user_action_upload_photo" = "{user} is sending photo";
|
"lng_user_action_upload_photo" = "{user} is sending a photo";
|
||||||
"lng_send_action_upload_file" = "sending file";
|
"lng_send_action_upload_file" = "sending a file";
|
||||||
"lng_user_action_upload_file" = "{user} is sending file";
|
"lng_user_action_upload_file" = "{user} is sending a file";
|
||||||
"lng_send_action_geo_location" = "picking location";
|
"lng_send_action_geo_location" = "picking a location";
|
||||||
"lng_user_action_geo_location" = "{user} is picking location";
|
"lng_user_action_geo_location" = "{user} is picking a location";
|
||||||
"lng_send_action_choose_contact" = "choosing contact";
|
"lng_send_action_choose_contact" = "choosing a contact";
|
||||||
"lng_user_action_choose_contact" = "{user} is choosing contact";
|
"lng_user_action_choose_contact" = "{user} is choosing a contact";
|
||||||
"lng_unread_bar" = "{count:_not_used_|# unread message|# unread messages}";
|
"lng_unread_bar" = "{count:_not_used_|# unread message|# unread messages}";
|
||||||
|
|
||||||
"lng_maps_point" = "Location";
|
"lng_maps_point" = "Location";
|
||||||
"lng_save_photo" = "Save image";
|
"lng_save_photo" = "Save image";
|
||||||
"lng_save_video" = "Save video";
|
"lng_save_video" = "Save video file";
|
||||||
"lng_save_audio" = "Save audio";
|
"lng_save_audio_file" = "Save audio file";
|
||||||
|
"lng_save_audio" = "Save voice message";
|
||||||
"lng_save_file" = "Save file";
|
"lng_save_file" = "Save file";
|
||||||
"lng_save_downloaded" = "{ready} / {total} {mb}";
|
"lng_save_downloaded" = "{ready} / {total} {mb}";
|
||||||
"lng_duration_and_size" = "{duration}, {size}";
|
"lng_duration_and_size" = "{duration}, {size}";
|
||||||
|
@ -700,16 +760,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_view_group" = "View group info";
|
"lng_context_view_group" = "View group info";
|
||||||
"lng_context_view_channel" = "View channel info";
|
"lng_context_view_channel" = "View channel info";
|
||||||
|
|
||||||
"lng_context_open_link" = "Open Link";
|
|
||||||
"lng_context_copy_link" = "Copy Link";
|
"lng_context_copy_link" = "Copy Link";
|
||||||
"lng_context_open_email" = "Write to this address";
|
"lng_context_copy_post_link" = "Copy Post Link";
|
||||||
"lng_context_copy_email" = "Copy email address";
|
"lng_context_copy_email" = "Copy email address";
|
||||||
"lng_context_open_hashtag" = "Search by hashtag";
|
|
||||||
"lng_context_copy_hashtag" = "Copy hashtag";
|
"lng_context_copy_hashtag" = "Copy hashtag";
|
||||||
"lng_context_open_mention" = "Open profile";
|
|
||||||
"lng_context_copy_mention" = "Copy username";
|
"lng_context_copy_mention" = "Copy username";
|
||||||
"lng_context_open_image" = "Open Image";
|
"lng_context_save_image" = "Save Image As...";
|
||||||
"lng_context_save_image" = "Save Image As..";
|
|
||||||
"lng_context_forward_image" = "Forward Image";
|
"lng_context_forward_image" = "Forward Image";
|
||||||
"lng_context_delete_image" = "Delete Image";
|
"lng_context_delete_image" = "Delete Image";
|
||||||
"lng_context_copy_image" = "Copy Image";
|
"lng_context_copy_image" = "Copy Image";
|
||||||
|
@ -717,14 +773,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_cancel_download" = "Cancel Download";
|
"lng_context_cancel_download" = "Cancel Download";
|
||||||
"lng_context_show_in_folder" = "Show in Folder";
|
"lng_context_show_in_folder" = "Show in Folder";
|
||||||
"lng_context_show_in_finder" = "Show in Finder";
|
"lng_context_show_in_finder" = "Show in Finder";
|
||||||
"lng_context_open_video" = "Open Video";
|
"lng_context_save_video" = "Save Video File As...";
|
||||||
"lng_context_save_video" = "Save Video As..";
|
"lng_context_save_audio_file" = "Save Audio File As...";
|
||||||
"lng_context_open_audio" = "Open Audio";
|
"lng_context_save_audio" = "Save Voice Message As...";
|
||||||
"lng_context_save_audio" = "Save Audio As..";
|
|
||||||
"lng_context_pack_info" = "Pack Info";
|
"lng_context_pack_info" = "Pack Info";
|
||||||
"lng_context_pack_add" = "Add Stickers";
|
"lng_context_pack_add" = "Add Stickers";
|
||||||
"lng_context_open_file" = "Open File";
|
"lng_context_save_file" = "Save File As...";
|
||||||
"lng_context_save_file" = "Save File As..";
|
|
||||||
"lng_context_forward_file" = "Forward File";
|
"lng_context_forward_file" = "Forward File";
|
||||||
"lng_context_delete_file" = "Delete File";
|
"lng_context_delete_file" = "Delete File";
|
||||||
"lng_context_close_file" = "Close File";
|
"lng_context_close_file" = "Close File";
|
||||||
|
@ -732,9 +786,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_save_gif" = "Save GIF";
|
"lng_context_save_gif" = "Save GIF";
|
||||||
"lng_context_to_msg" = "Go To Message";
|
"lng_context_to_msg" = "Go To Message";
|
||||||
"lng_context_reply_msg" = "Reply";
|
"lng_context_reply_msg" = "Reply";
|
||||||
|
"lng_context_edit_msg" = "Edit";
|
||||||
"lng_context_forward_msg" = "Forward Message";
|
"lng_context_forward_msg" = "Forward Message";
|
||||||
"lng_context_delete_msg" = "Delete Message";
|
"lng_context_delete_msg" = "Delete Message";
|
||||||
"lng_context_select_msg" = "Select Message";
|
"lng_context_select_msg" = "Select Message";
|
||||||
|
"lng_context_pin_msg" = "Pin Message";
|
||||||
|
"lng_context_unpin_msg" = "Unpin Message";
|
||||||
"lng_context_cancel_upload" = "Cancel Upload";
|
"lng_context_cancel_upload" = "Cancel Upload";
|
||||||
"lng_context_copy_selected" = "Copy Selected Text";
|
"lng_context_copy_selected" = "Copy Selected Text";
|
||||||
"lng_context_forward_selected" = "Forward Selected";
|
"lng_context_forward_selected" = "Forward Selected";
|
||||||
|
@ -748,7 +805,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_send_image_too_large" = "Could not send a file, because it is larger than 1.5 GB :(";
|
"lng_send_image_too_large" = "Could not send a file, because it is larger than 1.5 GB :(";
|
||||||
"lng_send_folder" = "Could not send «{name}» because it is a directory :(";
|
"lng_send_folder" = "Could not send «{name}» because it is a directory :(";
|
||||||
|
|
||||||
"lng_forward_choose" = "Choose recipient..";
|
"lng_forward_choose" = "Choose recipient...";
|
||||||
"lng_forward_cant" = "Sorry, no way to forward here :(";
|
"lng_forward_cant" = "Sorry, no way to forward here :(";
|
||||||
"lng_forward_confirm" = "Forward to {recipient}?";
|
"lng_forward_confirm" = "Forward to {recipient}?";
|
||||||
"lng_forward_share_contact" = "Share contact to {recipient}?";
|
"lng_forward_share_contact" = "Share contact to {recipient}?";
|
||||||
|
@ -768,6 +825,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_edit_group_title" = "Edit group name";
|
"lng_edit_group_title" = "Edit group name";
|
||||||
"lng_edit_contact_title" = "Edit contact name";
|
"lng_edit_contact_title" = "Edit contact name";
|
||||||
"lng_edit_channel_title" = "Edit channel";
|
"lng_edit_channel_title" = "Edit channel";
|
||||||
|
"lng_edit_sign_messages" = "Sign messages";
|
||||||
"lng_edit_group" = "Edit group";
|
"lng_edit_group" = "Edit group";
|
||||||
"lng_edit_self_title" = "Edit your name";
|
"lng_edit_self_title" = "Edit your name";
|
||||||
"lng_confirm_contact_data" = "New Contact";
|
"lng_confirm_contact_data" = "New Contact";
|
||||||
|
@ -793,7 +851,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_selected_delete" = "Delete";
|
"lng_selected_delete" = "Delete";
|
||||||
"lng_selected_forward" = "Forward";
|
"lng_selected_forward" = "Forward";
|
||||||
"lng_selected_count" = "{count:_not_used_|# message|# messages}";
|
"lng_selected_count" = "{count:_not_used_|# message|# messages}";
|
||||||
"lng_selected_cancel_sure_this" = "Do you want to cancel this upload?";
|
"lng_selected_cancel_sure_this" = "Cancel uploading?";
|
||||||
|
"lng_selected_upload_stop" = "Stop";
|
||||||
"lng_selected_delete_sure_this" = "Do you want to delete this message?";
|
"lng_selected_delete_sure_this" = "Do you want to delete this message?";
|
||||||
"lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?";
|
"lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?";
|
||||||
"lng_box_delete" = "Delete";
|
"lng_box_delete" = "Delete";
|
||||||
|
@ -809,7 +868,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
"lng_search_global_results" = "Global search results";
|
"lng_search_global_results" = "Global search results";
|
||||||
|
|
||||||
"lng_media_save_progress" = "{ready} of {total} {mb}";
|
"lng_media_save_progress" = "{ready} of {total} {mb}";
|
||||||
"lng_mediaview_save_as" = "Save As..";
|
"lng_mediaview_save_as" = "Save As...";
|
||||||
"lng_mediaview_copy" = "Copy";
|
"lng_mediaview_copy" = "Copy";
|
||||||
"lng_mediaview_forward" = "Forward";
|
"lng_mediaview_forward" = "Forward";
|
||||||
"lng_mediaview_delete" = "Delete";
|
"lng_mediaview_delete" = "Delete";
|
||||||
|
@ -832,7 +891,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
||||||
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
||||||
"lng_new_version_text" = "GIF revolution: 10x faster sending and downloading, autoplay, save your favorite GIFs to a dedicated tab on the sticker panel.\n\nMore about GIFs:\n{gifs_link}\n\nInline bots: A new way to add bot content to any chat. Type a bot's username and your query in the text field to get instant results and send them to your chat partner. Try typing “@gif dog” in your next chat. Sample bots: @gif, @wiki, @bing, @vid, @bold.\n\nMore about inline bots:\n{bots_link}\n\nAlso in this release: New cute design for media, automatic download settings for photos, voice messages and GIFs.";
|
"lng_new_version_text" = "— Visual improvements";
|
||||||
|
|
||||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
defaultFontFamily: 'Open Sans';
|
defaultFontFamily: 'Open Sans';
|
||||||
semibold: 'Open Sans Semibold';
|
semibold: 'Open Sans Semibold';
|
||||||
|
@ -51,7 +51,10 @@ color7: #2996ad; // sea
|
||||||
color8: #ce671b; // orange
|
color8: #ce671b; // orange
|
||||||
|
|
||||||
wndMinWidth: 380px;
|
wndMinWidth: 380px;
|
||||||
wideModeWidth: 640px;
|
|
||||||
|
adaptiveNormalWidth: 640px;
|
||||||
|
adaptiveWideWidth: 1366px;
|
||||||
|
|
||||||
wndMinHeight: 480px;
|
wndMinHeight: 480px;
|
||||||
wndDefWidth: 800px;
|
wndDefWidth: 800px;
|
||||||
wndDefHeight: 600px;
|
wndDefHeight: 600px;
|
||||||
|
@ -64,6 +67,13 @@ layerBg: black;
|
||||||
|
|
||||||
overBg: #edf2f5;
|
overBg: #edf2f5;
|
||||||
|
|
||||||
|
labelDefFlat: flatLabel {
|
||||||
|
font: font(fsize);
|
||||||
|
minWidth: 100px;
|
||||||
|
width: 0px;
|
||||||
|
align: align(left);
|
||||||
|
}
|
||||||
|
|
||||||
boxBg: white;
|
boxBg: white;
|
||||||
boxVerticalMargin: 10px;
|
boxVerticalMargin: 10px;
|
||||||
boxWidth: 320px;
|
boxWidth: 320px;
|
||||||
|
@ -72,6 +82,8 @@ boxPadding: margins(26px, 30px, 34px, 8px);
|
||||||
boxMaxListHeight: 600px;
|
boxMaxListHeight: 600px;
|
||||||
boxFontSize: 14px;
|
boxFontSize: 14px;
|
||||||
boxTextFont: font(boxFontSize);
|
boxTextFont: font(boxFontSize);
|
||||||
|
boxLittleSkip: 10px;
|
||||||
|
boxMediumSkip: 20px;
|
||||||
|
|
||||||
boxTitleFg: #444444;
|
boxTitleFg: #444444;
|
||||||
boxTitleFont: font(boxFontSize bold);
|
boxTitleFont: font(boxFontSize bold);
|
||||||
|
@ -123,6 +135,10 @@ redBoxLinkButton: linkButton(defaultBoxLinkButton) {
|
||||||
overColor: #d15948;
|
overColor: #d15948;
|
||||||
downColor: #db6352;
|
downColor: #db6352;
|
||||||
}
|
}
|
||||||
|
boxLabel: flatLabel(labelDefFlat) {
|
||||||
|
font: font(boxFontSize);
|
||||||
|
align: align(topleft);
|
||||||
|
}
|
||||||
|
|
||||||
defaultInputArea: InputArea {
|
defaultInputArea: InputArea {
|
||||||
textFg: black;
|
textFg: black;
|
||||||
|
@ -269,6 +285,21 @@ defaultPopupMenu: PopupMenu {
|
||||||
widthMin: 180px;
|
widthMin: 180px;
|
||||||
widthMax: 300px;
|
widthMax: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultTooltip: Tooltip {
|
||||||
|
textBg: #eef2f5;
|
||||||
|
textFg: #5d6c80;
|
||||||
|
textFont: normalFont;
|
||||||
|
textBorder: #c9d1db;
|
||||||
|
textPadding: margins(5px, 2px, 5px, 2px);
|
||||||
|
|
||||||
|
shift: point(-20px, 20px);
|
||||||
|
skip: 10px;
|
||||||
|
|
||||||
|
widthMax: 800px;
|
||||||
|
linesMax: 12;
|
||||||
|
}
|
||||||
|
|
||||||
almostTransparent: #ffffff0d;
|
almostTransparent: #ffffff0d;
|
||||||
boxScroll: flatScroll(solidScroll) {
|
boxScroll: flatScroll(solidScroll) {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
|
@ -593,13 +624,6 @@ scrollCountries: flatScroll(scrollDef) {
|
||||||
|
|
||||||
lnkText: #0f7dc7;
|
lnkText: #0f7dc7;
|
||||||
|
|
||||||
labelDefFlat: flatLabel {
|
|
||||||
font: font(fsize);
|
|
||||||
minWidth: 100px;
|
|
||||||
width: 0px;
|
|
||||||
align: align(left);
|
|
||||||
}
|
|
||||||
|
|
||||||
introBtnTop: 288px;
|
introBtnTop: 288px;
|
||||||
introSkip: 45px;
|
introSkip: 45px;
|
||||||
introFinishSkip: 15px;
|
introFinishSkip: 15px;
|
||||||
|
@ -937,6 +961,7 @@ dlgActiveUnreadColor: #5b94bf;
|
||||||
dlgActiveUnreadBG: white;
|
dlgActiveUnreadBG: white;
|
||||||
dlgActiveColor: white;
|
dlgActiveColor: white;
|
||||||
dlgActiveDateColor: #d3e2ee;
|
dlgActiveDateColor: #d3e2ee;
|
||||||
|
dlgActiveUnreadMutedBG: dlgActiveDateColor;
|
||||||
|
|
||||||
topBarHeight: 54px;
|
topBarHeight: 54px;
|
||||||
topBarBG: white;
|
topBarBG: white;
|
||||||
|
@ -950,6 +975,21 @@ topBarBackAlpha: 0.8;
|
||||||
topBarBackImg: sprite(65px, 112px, 9px, 16px);
|
topBarBackImg: sprite(65px, 112px, 9px, 16px);
|
||||||
topBarBackColor: #005faf;
|
topBarBackColor: #005faf;
|
||||||
topBarBackFont: font(16px);
|
topBarBackFont: font(16px);
|
||||||
|
topBarSearch: iconedButton(btnDefIconed) {
|
||||||
|
bgColor: transparent;
|
||||||
|
overBgColor: transparent;
|
||||||
|
|
||||||
|
icon: sprite(84px, 374px, 18px, 18px);
|
||||||
|
iconPos: point(13px, 18px);
|
||||||
|
downIcon: sprite(84px, 374px, 18px, 18px);
|
||||||
|
downIconPos: point(13px, 18px);
|
||||||
|
|
||||||
|
opacity: 0.22;
|
||||||
|
overOpacity: 0.36;
|
||||||
|
|
||||||
|
width: 44px;
|
||||||
|
height: topBarHeight;
|
||||||
|
}
|
||||||
topBarMinPadding: 5px;
|
topBarMinPadding: 5px;
|
||||||
topBarButton: flatButton(btnDefFlat) {
|
topBarButton: flatButton(btnDefFlat) {
|
||||||
color: btnYesColor;
|
color: btnYesColor;
|
||||||
|
@ -1009,10 +1049,11 @@ msgServiceNameFont: semiboldFont;
|
||||||
msgServicePhotoWidth: 100px;
|
msgServicePhotoWidth: 100px;
|
||||||
msgDateFont: font(13px);
|
msgDateFont: font(13px);
|
||||||
msgMinWidth: 190px;
|
msgMinWidth: 190px;
|
||||||
msgPhotoSize: 30px;
|
msgPhotoSize: 33px;
|
||||||
msgPhotoSkip: 40px;
|
msgPhotoSkip: 40px;
|
||||||
msgPadding: margins(13px, 7px, 13px, 8px);
|
msgPadding: margins(13px, 7px, 13px, 8px);
|
||||||
msgMargin: margins(13px, 4px, 53px, 4px);
|
msgMargin: margins(13px, 10px, 53px, 2px);
|
||||||
|
msgMarginTopAttached: 3px;
|
||||||
msgLnkPadding: 2px; // for media open / save links
|
msgLnkPadding: 2px; // for media open / save links
|
||||||
msgBorder: #f0f0f0;
|
msgBorder: #f0f0f0;
|
||||||
msgInBg: #fff;
|
msgInBg: #fff;
|
||||||
|
@ -1044,11 +1085,27 @@ msgInReplyBarColor: #2fa9e2;
|
||||||
msgOutReplyBarSelColor: #4da79f;
|
msgOutReplyBarSelColor: #4da79f;
|
||||||
msgInReplyBarSelColor: #2fa9e2;
|
msgInReplyBarSelColor: #2fa9e2;
|
||||||
|
|
||||||
|
msgBotKbDuration: 200;
|
||||||
|
msgBotKbFont: semiboldFont;
|
||||||
|
msgBotKbOverOpacity: 0.1;
|
||||||
|
msgBotKbIconPadding: 2px;
|
||||||
|
msgBotKbUrlIcon: sprite(188px, 338px, 10px, 10px);
|
||||||
|
msgBotKbCallbackIcon: msgBotKbUrlIcon;
|
||||||
|
msgBotKbRequestPhoneIcon: msgBotKbUrlIcon;
|
||||||
|
msgBotKbRequestLocationIcon: msgBotKbUrlIcon;
|
||||||
|
msgBotKbButton: botKeyboardButton {
|
||||||
|
margin: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
height: 36px;
|
||||||
|
textTop: 8px;
|
||||||
|
downTextTop: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
msgServiceBg: #89a0b47f;
|
msgServiceBg: #89a0b47f;
|
||||||
msgServiceSelectBg: #bbc8d4a2;
|
msgServiceSelectBg: #bbc8d4a2;
|
||||||
msgServiceColor: #FFF;
|
msgServiceColor: #FFF;
|
||||||
msgServicePadding: margins(12px, 3px, 12px, 4px);
|
msgServicePadding: margins(12px, 3px, 12px, 4px);
|
||||||
msgServiceMargin: margins(10px, 7px, 80px, 7px);
|
msgServiceMargin: margins(10px, 10px, 80px, 2px);
|
||||||
|
|
||||||
msgColor: #000;
|
msgColor: #000;
|
||||||
msgDateColor: #000;
|
msgDateColor: #000;
|
||||||
|
@ -1107,7 +1164,7 @@ collapseButton: flatButton(btnDefFlat) {
|
||||||
textTop: 3px;
|
textTop: 3px;
|
||||||
overTextTop: 3px;
|
overTextTop: 3px;
|
||||||
downTextTop: 3px;
|
downTextTop: 3px;
|
||||||
height: 24px;
|
height: 25px;
|
||||||
}
|
}
|
||||||
collapseHideDuration: 200;
|
collapseHideDuration: 200;
|
||||||
collapseShowDuration: 200;
|
collapseShowDuration: 200;
|
||||||
|
@ -1144,6 +1201,24 @@ outTextStyle: textStyle(defaultTextStyle) {
|
||||||
selectBg: msgOutBgSelected;
|
selectBg: msgOutBgSelected;
|
||||||
selectOverlay: msgSelectOverlay;
|
selectOverlay: msgSelectOverlay;
|
||||||
}
|
}
|
||||||
|
inFwdTextStyle: textStyle(defaultTextStyle) {
|
||||||
|
linkFlags: semiboldFont;
|
||||||
|
linkFlagsOver: semiboldFont;
|
||||||
|
linkFg: msgInServiceFg;
|
||||||
|
linkFgDown: msgInServiceFg;
|
||||||
|
}
|
||||||
|
outFwdTextStyle: textStyle(inFwdTextStyle) {
|
||||||
|
linkFg: msgOutServiceFg;
|
||||||
|
linkFgDown: msgOutServiceFg;
|
||||||
|
}
|
||||||
|
inFwdTextStyleSelected: textStyle(inFwdTextStyle) {
|
||||||
|
linkFg: msgInServiceFgSelected;
|
||||||
|
linkFgDown: msgInServiceFgSelected;
|
||||||
|
}
|
||||||
|
outFwdTextStyleSelected: textStyle(inFwdTextStyle) {
|
||||||
|
linkFg: msgOutServiceFgSelected;
|
||||||
|
linkFgDown: msgOutServiceFgSelected;
|
||||||
|
}
|
||||||
medviewSaveAsTextStyle: textStyle(defaultTextStyle) {
|
medviewSaveAsTextStyle: textStyle(defaultTextStyle) {
|
||||||
linkFg: #91d9ff;
|
linkFg: #91d9ff;
|
||||||
linkFgDown: #91d9ff;
|
linkFgDown: #91d9ff;
|
||||||
|
@ -1265,11 +1340,21 @@ msgFileBlue: sprite(60px, 425px, 20px, 20px);
|
||||||
msgFileOverDuration: 200;
|
msgFileOverDuration: 200;
|
||||||
msgFileRadialLine: 3px;
|
msgFileRadialLine: 3px;
|
||||||
|
|
||||||
msgFileExtPadding: 8px;
|
|
||||||
msgFileExtTop: 30px;
|
|
||||||
|
|
||||||
msgVideoSize: size(320px, 240px);
|
msgVideoSize: size(320px, 240px);
|
||||||
|
|
||||||
|
msgWaveformBar: 2px;
|
||||||
|
msgWaveformSkip: 1px;
|
||||||
|
msgWaveformMin: 2px;
|
||||||
|
msgWaveformMax: 20px;
|
||||||
|
msgWaveformInActive: #59b6eb;
|
||||||
|
msgWaveformInActiveSelected: #51a3d3;
|
||||||
|
msgWaveformInInactive: #d4dee6;
|
||||||
|
msgWaveformInInactiveSelected: #9cc1e1;
|
||||||
|
msgWaveformOutActive: #78c67f;
|
||||||
|
msgWaveformOutActiveSelected: #6badad;
|
||||||
|
msgWaveformOutInactive: #b3e2b4;
|
||||||
|
msgWaveformOutInactiveSelected: #91c3c3;
|
||||||
|
|
||||||
sendPadding: 9px;
|
sendPadding: 9px;
|
||||||
btnSend: flatButton(btnDefFlat) {
|
btnSend: flatButton(btnDefFlat) {
|
||||||
color: btnYesColor;
|
color: btnYesColor;
|
||||||
|
@ -1349,7 +1434,7 @@ broadcastToggle: flatCheckbox {
|
||||||
bgColor: white;
|
bgColor: white;
|
||||||
disColor: black;
|
disColor: black;
|
||||||
|
|
||||||
width: 36px;
|
width: 34px;
|
||||||
height: 46px;
|
height: 46px;
|
||||||
duration: 200;
|
duration: 200;
|
||||||
bgFunc: transition(easeOutCirc);
|
bgFunc: transition(easeOutCirc);
|
||||||
|
@ -1364,13 +1449,23 @@ broadcastToggle: flatCheckbox {
|
||||||
disImageRect: sprite(18px, 125px, 22px, 21px);
|
disImageRect: sprite(18px, 125px, 22px, 21px);
|
||||||
chkDisImageRect: sprite(18px, 125px, 22px, 21px);
|
chkDisImageRect: sprite(18px, 125px, 22px, 21px);
|
||||||
|
|
||||||
imagePos: point(7px, 12px);
|
imagePos: point(6px, 12px);
|
||||||
|
}
|
||||||
|
silentToggle: flatCheckbox(broadcastToggle) {
|
||||||
|
width: 33px;
|
||||||
|
|
||||||
|
imageRect: sprite(354px, 242px, 21px, 21px);
|
||||||
|
chkImageRect: sprite(354px, 221px, 21px, 21px);
|
||||||
|
overImageRect: sprite(375px, 242px, 21px, 21px);
|
||||||
|
chkOverImageRect: sprite(375px, 221px, 21px, 21px);
|
||||||
|
disImageRect: sprite(354px, 242px, 21px, 21px);
|
||||||
|
chkDisImageRect: sprite(354px, 221px, 21px, 21px);
|
||||||
}
|
}
|
||||||
btnRecordAudio: sprite(379px, 390px, 16px, 24px);
|
btnRecordAudio: sprite(379px, 390px, 16px, 24px);
|
||||||
btnRecordAudioActive: sprite(379px, 366px, 16px, 24px);
|
btnRecordAudioActive: sprite(379px, 366px, 16px, 24px);
|
||||||
recordSignalColor: #f17077;
|
recordSignalColor: #f17077;
|
||||||
recordSignalMin: 5px;
|
recordSignalMin: 5px;
|
||||||
recordSignalMax: 10px;
|
recordSignalMax: 12px;
|
||||||
recordCancel: #aaa;
|
recordCancel: #aaa;
|
||||||
recordCancelActive: #ec6466;
|
recordCancelActive: #ec6466;
|
||||||
recordFont: font(13px);
|
recordFont: font(13px);
|
||||||
|
@ -1383,6 +1478,7 @@ replyTop: 8px;
|
||||||
replyBottom: 6px;
|
replyBottom: 6px;
|
||||||
replyIconPos: point(13px, 13px);
|
replyIconPos: point(13px, 13px);
|
||||||
replyIcon: sprite(343px, 197px, 24px, 24px);
|
replyIcon: sprite(343px, 197px, 24px, 24px);
|
||||||
|
editIcon: sprite(371px, 286px, 24px, 24px);
|
||||||
replyCancel: iconedButton(btnDefIconed) {
|
replyCancel: iconedButton(btnDefIconed) {
|
||||||
icon: sprite(165px, 24px, 14px, 14px);
|
icon: sprite(165px, 24px, 14px, 14px);
|
||||||
iconPos: point(17px, 17px);
|
iconPos: point(17px, 17px);
|
||||||
|
@ -1447,6 +1543,7 @@ reportSpamBg: #fffffff0;
|
||||||
newMsgSound: ':/gui/art/newmsg.wav';
|
newMsgSound: ':/gui/art/newmsg.wav';
|
||||||
|
|
||||||
unreadBarHeight: 32px;
|
unreadBarHeight: 32px;
|
||||||
|
unreadBarMargin: 8px;
|
||||||
unreadBarFont: semiboldFont;
|
unreadBarFont: semiboldFont;
|
||||||
unreadBarBG: #fcfbfa;
|
unreadBarBG: #fcfbfa;
|
||||||
unreadBarBorder: shadowColor;
|
unreadBarBorder: shadowColor;
|
||||||
|
@ -2017,17 +2114,17 @@ verifiedCheckInv: sprite(299px, 221px, 14px, 14px);
|
||||||
verifiedCheckPos: point(4px, 2px);
|
verifiedCheckPos: point(4px, 2px);
|
||||||
|
|
||||||
botKbDuration: 200;
|
botKbDuration: 200;
|
||||||
botKbBg: #f7f7f7;
|
botKbBg: #edf1f5;
|
||||||
botKbOverBg: #e8ecef;
|
botKbOverBg: #d8e2ec;
|
||||||
botKbDownBg: #dfe3e6;
|
botKbDownBg: #d8e2ec;
|
||||||
botKbColor: #8a8a8f;
|
botKbColor: #4b565f;
|
||||||
botKbFont: font(16px);
|
botKbFont: font(15px semibold);
|
||||||
botKbButton: botKeyboardButton {
|
botKbButton: botKeyboardButton {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
height: 36px;
|
height: 38px;
|
||||||
textTop: 8px;
|
textTop: 9px;
|
||||||
downTextTop: 9px;
|
downTextTop: 10px;
|
||||||
}
|
}
|
||||||
botKbTinyButton: botKeyboardButton {
|
botKbTinyButton: botKeyboardButton {
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
|
@ -2045,6 +2142,7 @@ minPhotoSize: 100px;
|
||||||
maxMediaSize: 420px;
|
maxMediaSize: 420px;
|
||||||
maxStickerSize: 256px;
|
maxStickerSize: 256px;
|
||||||
maxGifSize: 320px;
|
maxGifSize: 320px;
|
||||||
|
maxSignatureSize: 144px;
|
||||||
|
|
||||||
mvBgColor: #222;
|
mvBgColor: #222;
|
||||||
mvBgOpacity: 0.92;
|
mvBgOpacity: 0.92;
|
||||||
|
@ -2180,6 +2278,9 @@ overviewFileStatusTop: 27px;
|
||||||
overviewFileDateTop: 49px;
|
overviewFileDateTop: 49px;
|
||||||
overviewFileChecked: #2fa9e2;
|
overviewFileChecked: #2fa9e2;
|
||||||
overviewFileCheck: #00000066;
|
overviewFileCheck: #00000066;
|
||||||
|
overviewFileExtPadding: 5px;
|
||||||
|
overviewFileExtTop: 24px;
|
||||||
|
overviewFileExtFont: font(18px semibold);
|
||||||
|
|
||||||
// Mac specific
|
// Mac specific
|
||||||
|
|
||||||
|
@ -2376,7 +2477,7 @@ linksDateMargin: margins(0px, 15px, 0px, 2px);
|
||||||
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
|
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
|
||||||
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
|
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
|
||||||
|
|
||||||
inlineResultsLeft: 15px;
|
inlineResultsLeft: 11px;
|
||||||
inlineResultsSkip: 3px;
|
inlineResultsSkip: 3px;
|
||||||
inlineMediaHeight: 96px;
|
inlineMediaHeight: 96px;
|
||||||
inlineThumbSize: 64px;
|
inlineThumbSize: 64px;
|
||||||
|
@ -2385,5 +2486,12 @@ inlineDescriptionFg: #8a8a8a;
|
||||||
inlineRowMargin: 6px;
|
inlineRowMargin: 6px;
|
||||||
inlineRowBorder: linksBorder;
|
inlineRowBorder: linksBorder;
|
||||||
inlineRowBorderFg: linksBorderFg;
|
inlineRowBorderFg: linksBorderFg;
|
||||||
|
inlineRowFileNameTop: 2px;
|
||||||
|
inlineRowFileDescriptionTop: 23px;
|
||||||
inlineResultsMinWidth: 64px;
|
inlineResultsMinWidth: 64px;
|
||||||
inlineDurationMargin: 3px;
|
inlineDurationMargin: 3px;
|
||||||
|
|
||||||
|
editTextArea: InputArea(defaultInputArea) {
|
||||||
|
textMargins: margins(1px, 6px, 1px, 4px);
|
||||||
|
heightMax: 256px;
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
textStyle {
|
textStyle {
|
||||||
linkFlags: font;
|
linkFlags: font;
|
||||||
|
@ -272,6 +272,20 @@ PopupMenu {
|
||||||
widthMax: number;
|
widthMax: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tooltip {
|
||||||
|
textBg: color;
|
||||||
|
textFg: color;
|
||||||
|
textFont: font;
|
||||||
|
textBorder: color;
|
||||||
|
textPadding: margins;
|
||||||
|
|
||||||
|
shift: point;
|
||||||
|
skip: number;
|
||||||
|
|
||||||
|
widthMax: number;
|
||||||
|
linesMax: number;
|
||||||
|
}
|
||||||
|
|
||||||
botKeyboardButton {
|
botKeyboardButton {
|
||||||
margin: number;
|
margin: number;
|
||||||
padding: number;
|
padding: number;
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "genemoji.h"
|
#include "genemoji.h"
|
||||||
|
|
||||||
|
@ -1942,7 +1942,7 @@ In addition, as a special exception, the copyright holders give permission\n\
|
||||||
to link the code of portions of this program with the OpenSSL library.\n\
|
to link the code of portions of this program with the OpenSSL library.\n\
|
||||||
\n\
|
\n\
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n";
|
*/\n";
|
||||||
tcpp << "#include \"stdafx.h\"\n#include \"gui/emoji_config.h\"\n\n";
|
tcpp << "#include \"stdafx.h\"\n#include \"gui/emoji_config.h\"\n\n";
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "genlang.h"
|
#include "genlang.h"
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ bool genLang(const QString &lang_in, const QString &lang_out) {
|
||||||
th.setCodec("ISO 8859-1");
|
th.setCodec("ISO 8859-1");
|
||||||
th << "\
|
th << "\
|
||||||
/*\n\
|
/*\n\
|
||||||
Created from \'/Resources/lang.txt\' by \'/MetaLang\' project\n\
|
Created from \'/Resources/lang.strings\' by \'/MetaLang\' project\n\
|
||||||
\n\
|
\n\
|
||||||
WARNING! All changes made in this file will be lost!\n\
|
WARNING! All changes made in this file will be lost!\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -412,7 +412,7 @@ In addition, as a special exception, the copyright holders give permission\n\
|
||||||
to link the code of portions of this program with the OpenSSL library.\n\
|
to link the code of portions of this program with the OpenSSL library.\n\
|
||||||
\n\
|
\n\
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n";
|
*/\n";
|
||||||
th << "#pragma once\n\n";
|
th << "#pragma once\n\n";
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
||||||
|
|
||||||
tcpp << "\
|
tcpp << "\
|
||||||
/*\n\
|
/*\n\
|
||||||
Created from \'/Resources/lang.txt\' by \'/MetaLang\' project\n\
|
Created from \'/Resources/lang.strings\' by \'/MetaLang\' project\n\
|
||||||
\n\
|
\n\
|
||||||
WARNING! All changes made in this file will be lost!\n\
|
WARNING! All changes made in this file will be lost!\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -496,7 +496,7 @@ In addition, as a special exception, the copyright holders give permission\n\
|
||||||
to link the code of portions of this program with the OpenSSL library.\n\
|
to link the code of portions of this program with the OpenSSL library.\n\
|
||||||
\n\
|
\n\
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n";
|
*/\n";
|
||||||
tcpp << "#include \"stdafx.h\"\n#include \"lang.h\"\n\n";
|
tcpp << "#include \"stdafx.h\"\n#include \"lang.h\"\n\n";
|
||||||
tcpp << "namespace {\n";
|
tcpp << "namespace {\n";
|
||||||
|
@ -606,13 +606,22 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
||||||
++depth;
|
++depth;
|
||||||
current += ich;
|
current += ich;
|
||||||
|
|
||||||
if (tag == current) {
|
bool exact = (tag == current);
|
||||||
|
if (exact) {
|
||||||
tcpp << tab.repeated(depth + 1) << "if (ch + " << depth << " == e) {\n";
|
tcpp << tab.repeated(depth + 1) << "if (ch + " << depth << " == e) {\n";
|
||||||
tcpp << tab.repeated(depth + 1) << "\treturn lt_" << tag << ";\n";
|
tcpp << tab.repeated(depth + 1) << "\treturn lt_" << tag << ";\n";
|
||||||
tcpp << tab.repeated(depth + 1) << "}\n";
|
tcpp << tab.repeated(depth + 1) << "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpp << tab.repeated(depth + 1) << "if (ch + " << depth << " < e) switch (*(ch + " << depth << ")) {\n";
|
QByteArray nexttag = j.key();
|
||||||
|
if (exact && depth > 0 && nexttag.mid(0, depth) != current) {
|
||||||
|
current.chop(1);
|
||||||
|
--depth;
|
||||||
|
tcpp << tab.repeated(depth + 1) << "break;\n";
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
tcpp << tab.repeated(depth + 1) << "if (ch + " << depth << " < e) switch (*(ch + " << depth << ")) {\n";
|
||||||
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
@ -637,7 +646,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
||||||
tcpp << "\tswitch (*(ch + " << depth << ")) {\n";
|
tcpp << "\tswitch (*(ch + " << depth << ")) {\n";
|
||||||
for (LangKeys::const_iterator i = keys.cbegin(), j = i + 1, e = keys.cend(); i != e; ++i) {
|
for (LangKeys::const_iterator i = keys.cbegin(), j = i + 1, e = keys.cend(); i != e; ++i) {
|
||||||
QByteArray key = i.key();
|
QByteArray key = i.key();
|
||||||
while (key.mid(0, depth) != current) {
|
while (depth > 0 && key.mid(0, depth) != current) {
|
||||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||||
current.chop(1);
|
current.chop(1);
|
||||||
--depth;
|
--depth;
|
||||||
|
@ -661,13 +670,22 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
||||||
++depth;
|
++depth;
|
||||||
current += ich;
|
current += ich;
|
||||||
|
|
||||||
if (key == current) {
|
bool exact = (key == current);
|
||||||
|
if (exact) {
|
||||||
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " == e) {\n";
|
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " == e) {\n";
|
||||||
tcpp << tab.repeated(depth - 3) << "\treturn " << key << (keysTags[key].isEmpty() ? "" : "__tagged") << ";\n";
|
tcpp << tab.repeated(depth - 3) << "\treturn " << key << (keysTags[key].isEmpty() ? "" : "__tagged") << ";\n";
|
||||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " < e) switch (*(ch + " << depth << ")) {\n";
|
QByteArray nextkey = j.key();
|
||||||
|
if (exact && depth > 0 && nextkey.mid(0, depth) != current) {
|
||||||
|
current.chop(1);
|
||||||
|
--depth;
|
||||||
|
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " < e) switch (*(ch + " << depth << ")) {\n";
|
||||||
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
@ -707,16 +725,25 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
||||||
tcpp << "\tif (index >= lngtags_max_counted_values) return lngkeys_cnt;\n\n";
|
tcpp << "\tif (index >= lngtags_max_counted_values) return lngkeys_cnt;\n\n";
|
||||||
if (!tags.isEmpty()) {
|
if (!tags.isEmpty()) {
|
||||||
tcpp << "\tswitch (key) {\n";
|
tcpp << "\tswitch (key) {\n";
|
||||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
for (auto key : keysOrder) {
|
||||||
QVector<QByteArray> &tagsList(keysTags[keysOrder[i]]);
|
QVector<QByteArray> &tagsList(keysTags[key]);
|
||||||
if (tagsList.isEmpty()) continue;
|
if (tagsList.isEmpty()) continue;
|
||||||
|
|
||||||
QMap<QByteArray, QVector<QString> > &countedTags(keysCounted[keysOrder[i]]);
|
QMap<QByteArray, QVector<QString> > &countedTags(keysCounted[key]);
|
||||||
tcpp << "\tcase " << keysOrder[i] << "__tagged: {\n";
|
bool hasCounted = false;
|
||||||
|
for (auto tag : tagsList) {
|
||||||
|
if (!countedTags[tag].isEmpty()) {
|
||||||
|
hasCounted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasCounted) continue;
|
||||||
|
|
||||||
|
tcpp << "\tcase " << key << "__tagged: {\n";
|
||||||
tcpp << "\t\tswitch (tag) {\n";
|
tcpp << "\t\tswitch (tag) {\n";
|
||||||
for (int j = 0, s = tagsList.size(); j < s; ++j) {
|
for (auto tag : tagsList) {
|
||||||
if (!countedTags[tagsList[j]].isEmpty()) {
|
if (!countedTags[tag].isEmpty()) {
|
||||||
tcpp << "\t\tcase lt_" << tagsList[j] << ": return LangKey(" << keysOrder[i] << "__" << tagsList[j] << "0 + index);\n";
|
tcpp << "\t\tcase lt_" << tag << ": return LangKey(" << key << "__" << tag << "0 + index);\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tcpp << "\t\t}\n";
|
tcpp << "\t\t}\n";
|
||||||
|
@ -724,7 +751,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
||||||
}
|
}
|
||||||
tcpp << "\t}\n\n";
|
tcpp << "\t}\n\n";
|
||||||
}
|
}
|
||||||
tcpp << "\treturn lngkeys_cnt;";
|
tcpp << "\treturn lngkeys_cnt;\n";
|
||||||
tcpp << "}\n\n";
|
tcpp << "}\n\n";
|
||||||
|
|
||||||
tcpp << "bool LangLoader::feedKeyValue(LangKey key, const QString &value) {\n";
|
tcpp << "bool LangLoader::feedKeyValue(LangKey key, const QString &value) {\n";
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "genstyles.h"
|
#include "genstyles.h"
|
||||||
|
|
||||||
|
@ -381,9 +381,9 @@ In addition, as a special exception, the copyright holders give permission\n\
|
||||||
to link the code of portions of this program with the OpenSSL library.\n\
|
to link the code of portions of this program with the OpenSSL library.\n\
|
||||||
\n\
|
\n\
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n";
|
*/\n";
|
||||||
tout << "#pragma once\n\n#include \"style.h\"\n\nnamespace style {\n";
|
tout << "#pragma once\n\n#include \"gui/style.h\"\n\nnamespace style {\n";
|
||||||
for (int i = 0, l = byIndex.size(); i < l; ++i) {
|
for (int i = 0, l = byIndex.size(); i < l; ++i) {
|
||||||
ClassData &cls(byIndex[i]);
|
ClassData &cls(byIndex[i]);
|
||||||
classes.insert(cls.name, cls);
|
classes.insert(cls.name, cls);
|
||||||
|
@ -1542,9 +1542,9 @@ In addition, as a special exception, the copyright holders give permission\n\
|
||||||
to link the code of portions of this program with the OpenSSL library.\n\
|
to link the code of portions of this program with the OpenSSL library.\n\
|
||||||
\n\
|
\n\
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n";
|
*/\n";
|
||||||
tout << "#pragma once\n\n#include \"style.h\"\n\nnamespace st {\n";
|
tout << "#pragma once\n\n#include \"gui/style.h\"\n\nnamespace st {\n";
|
||||||
tcpp << "\
|
tcpp << "\
|
||||||
/*\n\
|
/*\n\
|
||||||
Created from \'/Resources/style.txt\' by \'/MetaStyle\' project\n\
|
Created from \'/Resources/style.txt\' by \'/MetaStyle\' project\n\
|
||||||
|
@ -1568,7 +1568,7 @@ In addition, as a special exception, the copyright holders give permission\n\
|
||||||
to link the code of portions of this program with the OpenSSL library.\n\
|
to link the code of portions of this program with the OpenSSL library.\n\
|
||||||
\n\
|
\n\
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n";
|
*/\n";
|
||||||
tcpp << "#include \"stdafx.h\"\n#include \"style_auto.h\"\n\nnamespace {\n";
|
tcpp << "#include \"stdafx.h\"\n#include \"style_auto.h\"\n\nnamespace {\n";
|
||||||
for (int i = 0, l = scalars.size(); i < l; ++i) {
|
for (int i = 0, l = scalars.size(); i < l; ++i) {
|
||||||
|
@ -1945,7 +1945,7 @@ In addition, as a special exception, the copyright holders give permission\n\
|
||||||
to link the code of portions of this program with the OpenSSL library.\n\
|
to link the code of portions of this program with the OpenSSL library.\n\
|
||||||
\n\
|
\n\
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org\n\
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n";
|
*/\n";
|
||||||
tnum << "#include \"stdafx.h\"\n#include \"numbers.h\"\n\n";
|
tnum << "#include \"stdafx.h\"\n#include \"numbers.h\"\n\n";
|
||||||
tnum << "QVector<int> phoneNumberParse(const QString &number) {\n";
|
tnum << "QVector<int> phoneNumberParse(const QString &number) {\n";
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "memain.h"
|
#include "memain.h"
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "mlmain.h"
|
#include "mlmain.h"
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "msmain.h"
|
#include "msmain.h"
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "packer.h"
|
#include "packer.h"
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "updater.h"
|
#include "updater.h"
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ bool update() {
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (copyTries < 30);
|
} while (copyTries < 100);
|
||||||
if (!copyResult) {
|
if (!copyResult) {
|
||||||
writeLog(L"Error: failed to copy, asking to retry..");
|
writeLog(L"Error: failed to copy, asking to retry..");
|
||||||
WCHAR errMsg[2048];
|
WCHAR errMsg[2048];
|
||||||
|
@ -328,14 +328,11 @@ void updateRegistry() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <ShlObj.h>
|
|
||||||
|
|
||||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdParamarg, int cmdShow) {
|
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdParamarg, int cmdShow) {
|
||||||
openLog();
|
openLog();
|
||||||
|
|
||||||
#ifdef _NEED_WIN_GENERATE_DUMP
|
|
||||||
_oldWndExceptionFilter = SetUnhandledExceptionFilter(_exceptionFilter);
|
_oldWndExceptionFilter = SetUnhandledExceptionFilter(_exceptionFilter);
|
||||||
#endif
|
// CAPIHook apiHook("kernel32.dll", "SetUnhandledExceptionFilter", (PROC)RedirectedSetUnhandledExceptionFilter);
|
||||||
|
|
||||||
writeLog(L"Updaters started..");
|
writeLog(L"Updaters started..");
|
||||||
|
|
||||||
|
@ -459,13 +456,12 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdPara
|
||||||
ShellExecute(0, 0, (updateTo + L"Telegram.exe").c_str(), (L"-noupdate" + targs).c_str(), 0, SW_SHOWNORMAL);
|
ShellExecute(0, 0, (updateTo + L"Telegram.exe").c_str(), (L"-noupdate" + targs).c_str(), 0, SW_SHOWNORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeLog(L"Executed Telegram.exe, closing log and quiting..");
|
writeLog(L"Executed Telegram.exe, closing log and quitting..");
|
||||||
closeLog();
|
closeLog();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _NEED_WIN_GENERATE_DUMP
|
|
||||||
static const WCHAR *_programName = L"Telegram Desktop"; // folder in APPDATA, if current path is unavailable for writing
|
static const WCHAR *_programName = L"Telegram Desktop"; // folder in APPDATA, if current path is unavailable for writing
|
||||||
static const WCHAR *_exeName = L"Updater.exe";
|
static const WCHAR *_exeName = L"Updater.exe";
|
||||||
|
|
||||||
|
@ -486,13 +482,18 @@ HANDLE _generateDumpFileAtPath(const WCHAR *path) {
|
||||||
static const int maxFileLen = MAX_PATH * 10;
|
static const int maxFileLen = MAX_PATH * 10;
|
||||||
|
|
||||||
WCHAR szPath[maxFileLen];
|
WCHAR szPath[maxFileLen];
|
||||||
wsprintf(szPath, L"%stdumps\\", path);
|
wsprintf(szPath, L"%stdata\\", path);
|
||||||
|
|
||||||
if (!CreateDirectory(szPath, NULL)) {
|
if (!CreateDirectory(szPath, NULL)) {
|
||||||
if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wsprintf(szPath, L"%sdumps\\", path);
|
||||||
|
if (!CreateDirectory(szPath, NULL)) {
|
||||||
|
if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WCHAR szFileName[maxFileLen];
|
WCHAR szFileName[maxFileLen];
|
||||||
WCHAR szExeName[maxFileLen];
|
WCHAR szExeName[maxFileLen];
|
||||||
|
@ -564,4 +565,10 @@ LONG CALLBACK _exceptionFilter(EXCEPTION_POINTERS* pExceptionPointers) {
|
||||||
return _oldWndExceptionFilter ? (*_oldWndExceptionFilter)(pExceptionPointers) : EXCEPTION_CONTINUE_SEARCH;
|
return _oldWndExceptionFilter ? (*_oldWndExceptionFilter)(pExceptionPointers) : EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
// see http://www.codeproject.com/Articles/154686/SetUnhandledExceptionFilter-and-the-C-C-Runtime-Li
|
||||||
|
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI RedirectedSetUnhandledExceptionFilter(_In_opt_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) {
|
||||||
|
// When the CRT calls SetUnhandledExceptionFilter with NULL parameter
|
||||||
|
// our handler will not get removed.
|
||||||
|
_oldWndExceptionFilter = lpTopLevelExceptionFilter;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -16,13 +16,19 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4091)
|
||||||
#include <DbgHelp.h>
|
#include <DbgHelp.h>
|
||||||
|
#include <ShlObj.h>
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
#include <Shellapi.h>
|
#include <Shellapi.h>
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
|
@ -32,12 +38,9 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
using std::deque;
|
using std::deque;
|
||||||
using std::wstring;
|
using std::wstring;
|
||||||
|
|
||||||
#define _NEED_WIN_GENERATE_DUMP
|
|
||||||
|
|
||||||
#ifdef _NEED_WIN_GENERATE_DUMP
|
|
||||||
extern LPTOP_LEVEL_EXCEPTION_FILTER _oldWndExceptionFilter;
|
extern LPTOP_LEVEL_EXCEPTION_FILTER _oldWndExceptionFilter;
|
||||||
LONG CALLBACK _exceptionFilter(EXCEPTION_POINTERS* pExceptionPointers);
|
LONG CALLBACK _exceptionFilter(EXCEPTION_POINTERS* pExceptionPointers);
|
||||||
#endif _NEED_WIN_GENERATE_DUMP
|
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI RedirectedSetUnhandledExceptionFilter(_In_opt_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
|
||||||
|
|
||||||
static int updaterVersion = 1000;
|
static int updaterVersion = 1000;
|
||||||
static const WCHAR *updaterVersionStr = L"0.1.0";
|
static const WCHAR *updaterVersionStr = L"0.1.0";
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -324,7 +324,7 @@ bool update() {
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
bool needupdate = true, autostart = false, debug = false, tosettings = false, startintray = false, testmode = false;
|
bool needupdate = true, autostart = false, debug = false, tosettings = false, startintray = false, testmode = false;
|
||||||
|
|
||||||
char *key = 0;
|
char *key = 0, *crashreport = 0;
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if (equal(argv[i], "-noupdate")) {
|
if (equal(argv[i], "-noupdate")) {
|
||||||
needupdate = false;
|
needupdate = false;
|
||||||
|
@ -342,7 +342,9 @@ int main(int argc, char *argv[]) {
|
||||||
key = argv[i];
|
key = argv[i];
|
||||||
} else if (equal(argv[i], "-workpath") && ++i < argc) {
|
} else if (equal(argv[i], "-workpath") && ++i < argc) {
|
||||||
workDir = argv[i];
|
workDir = argv[i];
|
||||||
}
|
} else if (equal(argv[i], "-crashreport") && ++i < argc) {
|
||||||
|
crashreport = argv[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
openLog();
|
openLog();
|
||||||
|
|
||||||
|
@ -408,24 +410,27 @@ int main(int argc, char *argv[]) {
|
||||||
char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_startintray[] = "-startintray", p_testmode[] = "-testmode";
|
char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_startintray[] = "-startintray", p_testmode[] = "-testmode";
|
||||||
int argIndex = 0;
|
int argIndex = 0;
|
||||||
args[argIndex++] = path;
|
args[argIndex++] = path;
|
||||||
args[argIndex++] = p_noupdate;
|
if (crashreport) {
|
||||||
if (autostart) args[argIndex++] = p_autostart;
|
args[argIndex++] = crashreport;
|
||||||
if (debug) args[argIndex++] = p_debug;
|
} else {
|
||||||
if (startintray) args[argIndex++] = p_startintray;
|
args[argIndex++] = p_noupdate;
|
||||||
if (testmode) args[argIndex++] = p_testmode;
|
if (autostart) args[argIndex++] = p_autostart;
|
||||||
if (tosettings) args[argIndex++] = p_tosettings;
|
if (debug) args[argIndex++] = p_debug;
|
||||||
if (key) {
|
if (startintray) args[argIndex++] = p_startintray;
|
||||||
args[argIndex++] = p_key;
|
if (testmode) args[argIndex++] = p_testmode;
|
||||||
args[argIndex++] = key;
|
if (tosettings) args[argIndex++] = p_tosettings;
|
||||||
}
|
if (key) {
|
||||||
|
args[argIndex++] = p_key;
|
||||||
|
args[argIndex++] = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
switch (pid) {
|
switch (pid) {
|
||||||
case -1: writeLog("fork() failed!"); return 1;
|
case -1: writeLog("fork() failed!"); return 1;
|
||||||
case 0: execv(path, args); return 1;
|
case 0: execv(path, args); return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeLog("Executed Telegram, closing log and quiting..");
|
writeLog("Executed Telegram, closing log and quitting..");
|
||||||
closeLog();
|
closeLog();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -16,13 +16,14 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
NSString *appName = @"Telegram.app";
|
NSString *appName = @"Telegram.app";
|
||||||
NSString *appDir = nil;
|
NSString *appDir = nil;
|
||||||
NSString *workDir = nil;
|
NSString *workDir = nil;
|
||||||
|
NSString *crashReportArg = nil;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
BOOL _debug = YES;
|
BOOL _debug = YES;
|
||||||
|
@ -101,6 +102,10 @@ int main(int argc, const char * argv[]) {
|
||||||
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
|
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
|
||||||
procId = [[formatter numberFromString:[NSString stringWithUTF8String:argv[i]]] intValue];
|
procId = [[formatter numberFromString:[NSString stringWithUTF8String:argv[i]]] intValue];
|
||||||
}
|
}
|
||||||
|
} else if ([@"-crashreport" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
||||||
|
if (++i < argc) {
|
||||||
|
crashReportArg = [NSString stringWithUTF8String:argv[i]];
|
||||||
|
}
|
||||||
} else if ([@"-noupdate" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
} else if ([@"-noupdate" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
||||||
update = NO;
|
update = NO;
|
||||||
} else if ([@"-tosettings" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
} else if ([@"-tosettings" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
||||||
|
@ -214,15 +219,17 @@ int main(int argc, const char * argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *appPath = [[NSArray arrayWithObjects:appDir, appRealName, nil] componentsJoinedByString:@""];
|
NSString *appPath = [[NSArray arrayWithObjects:appDir, appRealName, nil] componentsJoinedByString:@""];
|
||||||
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:@"-noupdate", nil];
|
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects: crashReportArg ? crashReportArg : @"-noupdate", nil];
|
||||||
if (toSettings) [args addObject:@"-tosettings"];
|
if (!crashReportArg) {
|
||||||
if (_debug) [args addObject:@"-debug"];
|
if (toSettings) [args addObject:@"-tosettings"];
|
||||||
if (startInTray) [args addObject:@"-startintray"];
|
if (_debug) [args addObject:@"-debug"];
|
||||||
if (testMode) [args addObject:@"-testmode"];
|
if (startInTray) [args addObject:@"-startintray"];
|
||||||
if (autoStart) [args addObject:@"-autostart"];
|
if (testMode) [args addObject:@"-testmode"];
|
||||||
if (key) {
|
if (autoStart) [args addObject:@"-autostart"];
|
||||||
[args addObject:@"-key"];
|
if (key) {
|
||||||
[args addObject:key];
|
[args addObject:@"-key"];
|
||||||
|
[args addObject:key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
writeLog([[NSArray arrayWithObjects:@"Running application '", appPath, @"' with args '", [args componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]);
|
writeLog([[NSArray arrayWithObjects:@"Running application '", appPath, @"' with args '", [args componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]);
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
|
|
|
@ -16,10 +16,10 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "style.h"
|
#include "gui/style.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
@ -29,89 +29,65 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
ApiWrap::ApiWrap(QObject *parent) : QObject(parent) {
|
ApiWrap::ApiWrap(QObject *parent) : QObject(parent)
|
||||||
|
, _messageDataResolveDelayed(new SingleDelayedCall(this, "resolveMessageDatas")) {
|
||||||
App::initBackground();
|
App::initBackground();
|
||||||
|
|
||||||
connect(&_replyToTimer, SIGNAL(timeout()), this, SLOT(resolveReplyTo()));
|
|
||||||
connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages()));
|
connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::init() {
|
void ApiWrap::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::itemRemoved(HistoryItem *item) {
|
void ApiWrap::requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback *callback) {
|
||||||
if (HistoryReply *reply = item->toHistoryReply()) {
|
MessageDataRequest::CallbackPtr pcallback(callback);
|
||||||
ChannelData *channel = reply->history()->peer->asChannel();
|
MessageDataRequest &req(channel ? _channelMessageDataRequests[channel][msgId] : _messageDataRequests[msgId]);
|
||||||
ReplyToRequests *requests(replyToRequests(channel, true));
|
req.callbacks.append(pcallback);
|
||||||
if (requests) {
|
if (!req.req) _messageDataResolveDelayed->call();
|
||||||
ReplyToRequests::iterator i = requests->find(reply->replyToId());
|
|
||||||
if (i != requests->cend()) {
|
|
||||||
for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
|
|
||||||
if ((*j) == reply) {
|
|
||||||
j = i->replies.erase(j);
|
|
||||||
} else {
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i->replies.isEmpty()) {
|
|
||||||
requests->erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (channel && requests->isEmpty()) {
|
|
||||||
_channelReplyToRequests.remove(channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::requestReplyTo(HistoryReply *reply, ChannelData *channel, MsgId id) {
|
ApiWrap::MessageIds ApiWrap::collectMessageIds(const MessageDataRequests &requests) {
|
||||||
ReplyToRequest &req(channel ? _channelReplyToRequests[channel][id] : _replyToRequests[id]);
|
|
||||||
req.replies.append(reply);
|
|
||||||
if (!req.req) _replyToTimer.start(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiWrap::MessageIds ApiWrap::collectMessageIds(const ReplyToRequests &requests) {
|
|
||||||
MessageIds result;
|
MessageIds result;
|
||||||
result.reserve(requests.size());
|
result.reserve(requests.size());
|
||||||
for (ReplyToRequests::const_iterator i = requests.cbegin(), e = requests.cend(); i != e; ++i) {
|
for (MessageDataRequests::const_iterator i = requests.cbegin(), e = requests.cend(); i != e; ++i) {
|
||||||
if (i.value().req > 0) continue;
|
if (i.value().req > 0) continue;
|
||||||
result.push_back(MTP_int(i.key()));
|
result.push_back(MTP_int(i.key()));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiWrap::ReplyToRequests *ApiWrap::replyToRequests(ChannelData *channel, bool onlyExisting) {
|
ApiWrap::MessageDataRequests *ApiWrap::messageDataRequests(ChannelData *channel, bool onlyExisting) {
|
||||||
if (channel) {
|
if (channel) {
|
||||||
ChannelReplyToRequests::iterator i = _channelReplyToRequests.find(channel);
|
ChannelMessageDataRequests::iterator i = _channelMessageDataRequests.find(channel);
|
||||||
if (i == _channelReplyToRequests.cend()) {
|
if (i == _channelMessageDataRequests.cend()) {
|
||||||
if (onlyExisting) return 0;
|
if (onlyExisting) return 0;
|
||||||
i = _channelReplyToRequests.insert(channel, ReplyToRequests());
|
i = _channelMessageDataRequests.insert(channel, MessageDataRequests());
|
||||||
}
|
}
|
||||||
return &i.value();
|
return &i.value();
|
||||||
}
|
}
|
||||||
return &_replyToRequests;
|
return &_messageDataRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::resolveReplyTo() {
|
void ApiWrap::resolveMessageDatas() {
|
||||||
if (_replyToRequests.isEmpty() && _channelReplyToRequests.isEmpty()) return;
|
if (_messageDataRequests.isEmpty() && _channelMessageDataRequests.isEmpty()) return;
|
||||||
|
|
||||||
MessageIds ids = collectMessageIds(_replyToRequests);
|
MessageIds ids = collectMessageIds(_messageDataRequests);
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotReplyTo, (ChannelData*)0), RPCFailHandlerPtr(), 0, 5);
|
mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotMessageDatas, (ChannelData*)nullptr), RPCFailHandlerPtr(), 0, 5);
|
||||||
for (ReplyToRequests::iterator i = _replyToRequests.begin(); i != _replyToRequests.cend(); ++i) {
|
for (MessageDataRequests::iterator i = _messageDataRequests.begin(); i != _messageDataRequests.cend(); ++i) {
|
||||||
if (i.value().req > 0) continue;
|
if (i.value().req > 0) continue;
|
||||||
i.value().req = req;
|
i.value().req = req;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ChannelReplyToRequests::iterator j = _channelReplyToRequests.begin(); j != _channelReplyToRequests.cend();) {
|
for (ChannelMessageDataRequests::iterator j = _channelMessageDataRequests.begin(); j != _channelMessageDataRequests.cend();) {
|
||||||
if (j->isEmpty()) {
|
if (j->isEmpty()) {
|
||||||
j = _channelReplyToRequests.erase(j);
|
j = _channelMessageDataRequests.erase(j);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MessageIds ids = collectMessageIds(j.value());
|
MessageIds ids = collectMessageIds(j.value());
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
mtpRequestId req = MTP::send(MTPchannels_GetMessages(j.key()->inputChannel, MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotReplyTo, j.key()), RPCFailHandlerPtr(), 0, 5);
|
mtpRequestId req = MTP::send(MTPchannels_GetMessages(j.key()->inputChannel, MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotMessageDatas, j.key()), RPCFailHandlerPtr(), 0, 5);
|
||||||
for (ReplyToRequests::iterator i = j->begin(); i != j->cend(); ++i) {
|
for (MessageDataRequests::iterator i = j->begin(); i != j->cend(); ++i) {
|
||||||
if (i.value().req > 0) continue;
|
if (i.value().req > 0) continue;
|
||||||
i.value().req = req;
|
i.value().req = req;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +96,7 @@ void ApiWrap::resolveReplyTo() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) {
|
void ApiWrap::gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) {
|
||||||
switch (msgs.type()) {
|
switch (msgs.type()) {
|
||||||
case mtpc_messages_messages: {
|
case mtpc_messages_messages: {
|
||||||
const MTPDmessages_messages &d(msgs.c_messages_messages());
|
const MTPDmessages_messages &d(msgs.c_messages_messages());
|
||||||
|
@ -141,10 +117,10 @@ void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs,
|
||||||
if (channel) {
|
if (channel) {
|
||||||
channel->ptsReceived(d.vpts.v);
|
channel->ptsReceived(d.vpts.v);
|
||||||
} else {
|
} else {
|
||||||
LOG(("App Error: received messages.channelMessages when no channel was passed! (ApiWrap::gotReplyTo)"));
|
LOG(("App Error: received messages.channelMessages when no channel was passed! (ApiWrap::gotDependencyItem)"));
|
||||||
}
|
}
|
||||||
if (d.has_collapsed()) { // should not be returned
|
if (d.has_collapsed()) { // should not be returned
|
||||||
LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (ApiWrap::gotReplyTo)"));
|
LOG(("API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (ApiWrap::gotDependencyItem)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
|
@ -152,16 +128,12 @@ void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs,
|
||||||
App::feedMsgs(d.vmessages, NewMessageExisting);
|
App::feedMsgs(d.vmessages, NewMessageExisting);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
ReplyToRequests *requests(replyToRequests(channel, true));
|
MessageDataRequests *requests(messageDataRequests(channel, true));
|
||||||
if (requests) {
|
if (requests) {
|
||||||
for (ReplyToRequests::iterator i = requests->begin(); i != requests->cend();) {
|
for (MessageDataRequests::iterator i = requests->begin(); i != requests->cend();) {
|
||||||
if (i.value().req == req) {
|
if (i.value().req == req) {
|
||||||
for (QList<HistoryReply*>::const_iterator j = i.value().replies.cbegin(), e = i.value().replies.cend(); j != e; ++j) {
|
for (MessageDataRequest::Callbacks::const_iterator j = i.value().callbacks.cbegin(), e = i.value().callbacks.cend(); j != e; ++j) {
|
||||||
if (*j) {
|
(*j)->call(channel, i.key());
|
||||||
(*j)->updateReplyTo(true);
|
|
||||||
} else {
|
|
||||||
App::main()->updateReplyTo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
i = requests->erase(i);
|
i = requests->erase(i);
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,7 +141,7 @@ void ApiWrap::gotReplyTo(ChannelData *channel, const MTPmessages_Messages &msgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (channel && requests->isEmpty()) {
|
if (channel && requests->isEmpty()) {
|
||||||
_channelReplyToRequests.remove(channel);
|
_channelMessageDataRequests.remove(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +230,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||||
}
|
}
|
||||||
if (f.has_migrated_from_chat_id()) {
|
if (f.has_migrated_from_chat_id()) {
|
||||||
if (!channel->mgInfo) {
|
if (!channel->mgInfo) {
|
||||||
channel->flags |= MTPDchannel::flag_megagroup;
|
channel->flags |= MTPDchannel::Flag::f_megagroup;
|
||||||
channel->flagsUpdated();
|
channel->flagsUpdated();
|
||||||
}
|
}
|
||||||
ChatData *cfrom = App::chat(peerFromChat(f.vmigrated_from_chat_id));
|
ChatData *cfrom = App::chat(peerFromChat(f.vmigrated_from_chat_id));
|
||||||
|
@ -273,7 +245,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||||
if (!h->isEmpty()) {
|
if (!h->isEmpty()) {
|
||||||
h->clear(true);
|
h->clear(true);
|
||||||
}
|
}
|
||||||
if (!hto->dialogs.isEmpty() && !h->dialogs.isEmpty()) {
|
if (hto->inChatList() && h->inChatList()) {
|
||||||
App::removeDialog(h);
|
App::removeDialog(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,6 +289,13 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||||
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (channel->isMegagroup()) {
|
||||||
|
if (f.has_pinned_msg_id()) {
|
||||||
|
channel->mgInfo->pinnedMsgId = f.vpinned_msg_id.v;
|
||||||
|
} else {
|
||||||
|
channel->mgInfo->pinnedMsgId = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
channel->fullUpdated();
|
channel->fullUpdated();
|
||||||
|
|
||||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings);
|
||||||
|
@ -344,12 +323,21 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
||||||
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req) {
|
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req) {
|
||||||
const MTPDuserFull &d(result.c_userFull());
|
const MTPDuserFull &d(result.c_userFull());
|
||||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
||||||
App::feedPhoto(d.vprofile_photo);
|
if (d.has_profile_photo()) {
|
||||||
|
App::feedPhoto(d.vprofile_photo);
|
||||||
|
}
|
||||||
App::feedUserLink(MTP_int(peerToUser(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link, false);
|
App::feedUserLink(MTP_int(peerToUser(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);
|
if (App::main()) {
|
||||||
|
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
|
||||||
|
}
|
||||||
|
|
||||||
peer->asUser()->setBotInfo(d.vbot_info);
|
if (d.has_bot_info()) {
|
||||||
peer->asUser()->blocked = mtpIsTrue(d.vblocked) ? UserIsBlocked : UserIsNotBlocked;
|
peer->asUser()->setBotInfo(d.vbot_info);
|
||||||
|
} else {
|
||||||
|
peer->asUser()->setBotInfoVersion(-1);
|
||||||
|
}
|
||||||
|
peer->asUser()->blocked = d.is_blocked() ? UserIsBlocked : UserIsNotBlocked;
|
||||||
|
peer->asUser()->about = d.has_about() ? qs(d.vabout) : QString();
|
||||||
|
|
||||||
if (req) {
|
if (req) {
|
||||||
QMap<PeerData*, mtpRequestId>::iterator i = _fullPeerRequests.find(peer);
|
QMap<PeerData*, mtpRequestId>::iterator i = _fullPeerRequests.find(peer);
|
||||||
|
@ -419,13 +407,13 @@ void ApiWrap::requestLastParticipants(ChannelData *peer, bool fromStart) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mtpRequestId req = MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsRecent(), MTP_int(fromStart ? 0 : peer->mgInfo->lastParticipants.size()), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer));
|
mtpRequestId req = MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsRecent(), MTP_int(fromStart ? 0 : peer->mgInfo->lastParticipants.size()), MTP_int(Global::ChatSizeMax())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer));
|
||||||
_participantsRequests.insert(peer, fromStart ? req : -req);
|
_participantsRequests.insert(peer, fromStart ? req : -req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::requestBots(ChannelData *peer) {
|
void ApiWrap::requestBots(ChannelData *peer) {
|
||||||
if (!peer || !peer->isMegagroup() || _botsRequests.contains(peer)) return;
|
if (!peer || !peer->isMegagroup() || _botsRequests.contains(peer)) return;
|
||||||
_botsRequests.insert(peer, MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)));
|
_botsRequests.insert(peer, MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(Global::ChatSizeMax())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
||||||
|
@ -524,7 +512,7 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
|
||||||
UserData *u = App::user(userId);
|
UserData *u = App::user(userId);
|
||||||
if (bots) {
|
if (bots) {
|
||||||
if (u->botInfo) {
|
if (u->botInfo) {
|
||||||
peer->mgInfo->bots.insert(u, true);
|
peer->mgInfo->bots.insert(u);
|
||||||
botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1;
|
botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1;
|
||||||
if (!u->botInfo->inited) {
|
if (!u->botInfo->inited) {
|
||||||
needBotsInfos = true;
|
needBotsInfos = true;
|
||||||
|
@ -536,9 +524,9 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
|
||||||
} else {
|
} else {
|
||||||
if (peer->mgInfo->lastParticipants.indexOf(u) < 0) {
|
if (peer->mgInfo->lastParticipants.indexOf(u) < 0) {
|
||||||
peer->mgInfo->lastParticipants.push_back(u);
|
peer->mgInfo->lastParticipants.push_back(u);
|
||||||
if (admin) peer->mgInfo->lastAdmins.insert(u, true);
|
if (admin) peer->mgInfo->lastAdmins.insert(u);
|
||||||
if (u->botInfo) {
|
if (u->botInfo) {
|
||||||
peer->mgInfo->bots.insert(u, true);
|
peer->mgInfo->bots.insert(u);
|
||||||
if (peer->mgInfo->botStatus != 0 && peer->mgInfo->botStatus < 2) {
|
if (peer->mgInfo->botStatus != 0 && peer->mgInfo->botStatus < 2) {
|
||||||
peer->mgInfo->botStatus = 2;
|
peer->mgInfo->botStatus = 2;
|
||||||
}
|
}
|
||||||
|
@ -645,15 +633,23 @@ void ApiWrap::kickParticipantDone(KickRequest kick, const MTPUpdates &result, mt
|
||||||
int32 i = kick.first->asChannel()->mgInfo->lastParticipants.indexOf(kick.second);
|
int32 i = kick.first->asChannel()->mgInfo->lastParticipants.indexOf(kick.second);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i);
|
kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i);
|
||||||
kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second);
|
|
||||||
}
|
}
|
||||||
kick.first->asChannel()->mgInfo->bots.remove(kick.second);
|
|
||||||
if (kick.first->asChannel()->count > 1) {
|
if (kick.first->asChannel()->count > 1) {
|
||||||
kick.first->asChannel()->count--;
|
--kick.first->asChannel()->count;
|
||||||
} else {
|
} else {
|
||||||
kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
|
kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
|
||||||
kick.first->asChannel()->mgInfo->lastParticipantsCount = 0;
|
kick.first->asChannel()->mgInfo->lastParticipantsCount = 0;
|
||||||
}
|
}
|
||||||
|
if (kick.first->asChannel()->mgInfo->lastAdmins.contains(kick.second)) {
|
||||||
|
kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second);
|
||||||
|
if (kick.first->asChannel()->adminsCount > 1) {
|
||||||
|
--kick.first->asChannel()->adminsCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kick.first->asChannel()->mgInfo->bots.remove(kick.second);
|
||||||
|
if (kick.first->asChannel()->mgInfo->bots.isEmpty() && kick.first->asChannel()->mgInfo->botStatus > 0) {
|
||||||
|
kick.first->asChannel()->mgInfo->botStatus = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
emit fullPeerUpdated(kick.first);
|
emit fullPeerUpdated(kick.first);
|
||||||
}
|
}
|
||||||
|
@ -672,9 +668,9 @@ void ApiWrap::scheduleStickerSetRequest(uint64 setId, uint64 access) {
|
||||||
|
|
||||||
void ApiWrap::requestStickerSets() {
|
void ApiWrap::requestStickerSets() {
|
||||||
for (QMap<uint64, QPair<uint64, mtpRequestId> >::iterator i = _stickerSetRequests.begin(), j = i, e = _stickerSetRequests.end(); i != e; i = j) {
|
for (QMap<uint64, QPair<uint64, mtpRequestId> >::iterator i = _stickerSetRequests.begin(), j = i, e = _stickerSetRequests.end(); i != e; i = j) {
|
||||||
|
++j;
|
||||||
if (i.value().second) continue;
|
if (i.value().second) continue;
|
||||||
|
|
||||||
++j;
|
|
||||||
int32 wait = (j == e) ? 0 : 10;
|
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);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -689,8 +685,8 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
|
||||||
if (d.vset.type() != mtpc_stickerSet) return;
|
if (d.vset.type() != mtpc_stickerSet) return;
|
||||||
const MTPDstickerSet &s(d.vset.c_stickerSet());
|
const MTPDstickerSet &s(d.vset.c_stickerSet());
|
||||||
|
|
||||||
StickerSets &sets(cRefStickerSets());
|
Stickers::Sets &sets(Global::RefStickerSets());
|
||||||
StickerSets::iterator it = sets.find(setId);
|
auto it = sets.find(setId);
|
||||||
if (it == sets.cend()) return;
|
if (it == sets.cend()) return;
|
||||||
|
|
||||||
it->access = s.vaccess_hash.v;
|
it->access = s.vaccess_hash.v;
|
||||||
|
@ -700,7 +696,7 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
|
||||||
it->flags = s.vflags.v;
|
it->flags = s.vflags.v;
|
||||||
|
|
||||||
const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v);
|
const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v);
|
||||||
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
auto custom = sets.find(Stickers::CustomSetId);
|
||||||
|
|
||||||
StickerPack pack;
|
StickerPack pack;
|
||||||
pack.reserve(d_docs.size());
|
pack.reserve(d_docs.size());
|
||||||
|
@ -731,12 +727,32 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pack.isEmpty()) {
|
if (pack.isEmpty()) {
|
||||||
int32 removeIndex = cStickerSetsOrder().indexOf(setId);
|
int removeIndex = Global::StickerSetsOrder().indexOf(setId);
|
||||||
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
|
if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
|
||||||
sets.erase(it);
|
sets.erase(it);
|
||||||
} else {
|
} else {
|
||||||
it->stickers = pack;
|
it->stickers = pack;
|
||||||
|
it->emoji.clear();
|
||||||
|
const QVector<MTPStickerPack> &v(d.vpacks.c_vector().v);
|
||||||
|
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||||
|
if (v.at(i).type() != mtpc_stickerPack) continue;
|
||||||
|
|
||||||
|
const MTPDstickerPack &pack(v.at(i).c_stickerPack());
|
||||||
|
if (EmojiPtr e = emojiGetNoColor(emojiFromText(qs(pack.vemoticon)))) {
|
||||||
|
const QVector<MTPlong> &stickers(pack.vdocuments.c_vector().v);
|
||||||
|
StickerPack p;
|
||||||
|
p.reserve(stickers.size());
|
||||||
|
for (int32 j = 0, c = stickers.size(); j < c; ++j) {
|
||||||
|
DocumentData *doc = App::document(stickers.at(j).v);
|
||||||
|
if (!doc || !doc->sticker()) continue;
|
||||||
|
|
||||||
|
p.push_back(doc);
|
||||||
|
}
|
||||||
|
it->emoji.insert(e, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeRecent) {
|
if (writeRecent) {
|
||||||
|
@ -887,10 +903,8 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
|
||||||
}
|
}
|
||||||
|
|
||||||
for (QMap<uint64, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
for (QMap<uint64, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
||||||
HistoryItem *item = App::histories().addNewMessage(v->at(i.value()), NewMessageExisting);
|
if (HistoryItem *item = App::histories().addNewMessage(v->at(i.value()), NewMessageExisting)) {
|
||||||
if (item) {
|
item->setPendingInitDimensions();
|
||||||
item->initDimensions();
|
|
||||||
Notify::historyItemResized(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,8 +916,7 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs
|
||||||
WebPageItems::const_iterator j = items.constFind(i.key());
|
WebPageItems::const_iterator j = items.constFind(i.key());
|
||||||
if (j != items.cend()) {
|
if (j != items.cend()) {
|
||||||
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
|
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
|
||||||
k.key()->initDimensions();
|
k.key()->setPendingInitDimensions();
|
||||||
Notify::historyItemResized(k.key());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -28,9 +28,8 @@ public:
|
||||||
ApiWrap(QObject *parent);
|
ApiWrap(QObject *parent);
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void itemRemoved(HistoryItem *item);
|
typedef SharedCallback<void, ChannelData*, MsgId> RequestMessageDataCallback;
|
||||||
|
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback *callback);
|
||||||
void requestReplyTo(HistoryReply *reply, ChannelData *channel, MsgId id);
|
|
||||||
|
|
||||||
void requestFullPeer(PeerData *peer);
|
void requestFullPeer(PeerData *peer);
|
||||||
void requestPeer(PeerData *peer);
|
void requestPeer(PeerData *peer);
|
||||||
|
@ -59,28 +58,30 @@ signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void resolveReplyTo();
|
void resolveMessageDatas();
|
||||||
void resolveWebPages();
|
void resolveWebPages();
|
||||||
|
|
||||||
void delayedRequestParticipantsCount();
|
void delayedRequestParticipantsCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void gotReplyTo(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
void gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
||||||
struct ReplyToRequest {
|
struct MessageDataRequest {
|
||||||
ReplyToRequest() : req(0) {
|
MessageDataRequest() : req(0) {
|
||||||
}
|
}
|
||||||
|
typedef SharedCallback<void, ChannelData*, MsgId>::Ptr CallbackPtr;
|
||||||
|
typedef QList<CallbackPtr> Callbacks;
|
||||||
mtpRequestId req;
|
mtpRequestId req;
|
||||||
QList<HistoryReply*> replies;
|
Callbacks callbacks;
|
||||||
};
|
};
|
||||||
typedef QMap<MsgId, ReplyToRequest> ReplyToRequests;
|
typedef QMap<MsgId, MessageDataRequest> MessageDataRequests;
|
||||||
ReplyToRequests _replyToRequests;
|
MessageDataRequests _messageDataRequests;
|
||||||
typedef QMap<ChannelData*, ReplyToRequests> ChannelReplyToRequests;
|
typedef QMap<ChannelData*, MessageDataRequests> ChannelMessageDataRequests;
|
||||||
ChannelReplyToRequests _channelReplyToRequests;
|
ChannelMessageDataRequests _channelMessageDataRequests;
|
||||||
SingleTimer _replyToTimer;
|
SingleDelayedCall *_messageDataResolveDelayed;
|
||||||
typedef QVector<MTPint> MessageIds;
|
typedef QVector<MTPint> MessageIds;
|
||||||
MessageIds collectMessageIds(const ReplyToRequests &requests);
|
MessageIds collectMessageIds(const MessageDataRequests &requests);
|
||||||
ReplyToRequests *replyToRequests(ChannelData *channel, bool onlyExisting = false);
|
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
|
||||||
|
|
||||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
||||||
void gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req);
|
void gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,13 +16,13 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "types.h"
|
#include "basic_types.h"
|
||||||
|
|
||||||
class Application;
|
class AppClass;
|
||||||
class Window;
|
class Window;
|
||||||
class MainWidget;
|
class MainWidget;
|
||||||
class SettingsWidget;
|
class SettingsWidget;
|
||||||
|
@ -36,30 +36,18 @@ class FileUploader;
|
||||||
|
|
||||||
typedef QMap<HistoryItem*, NullType> HistoryItemsMap;
|
typedef QMap<HistoryItem*, NullType> HistoryItemsMap;
|
||||||
typedef QHash<PhotoData*, HistoryItemsMap> PhotoItems;
|
typedef QHash<PhotoData*, HistoryItemsMap> PhotoItems;
|
||||||
typedef QHash<VideoData*, HistoryItemsMap> VideoItems;
|
|
||||||
typedef QHash<AudioData*, HistoryItemsMap> AudioItems;
|
|
||||||
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
|
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
|
||||||
typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
|
typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
|
||||||
typedef QHash<int32, HistoryItemsMap> SharedContactItems;
|
typedef QHash<int32, HistoryItemsMap> SharedContactItems;
|
||||||
typedef QHash<ClipReader*, HistoryItem*> GifItems;
|
typedef QHash<ClipReader*, HistoryItem*> GifItems;
|
||||||
|
|
||||||
typedef QHash<PhotoId, PhotoData*> PhotosData;
|
typedef QHash<PhotoId, PhotoData*> PhotosData;
|
||||||
typedef QHash<VideoId, VideoData*> VideosData;
|
|
||||||
typedef QHash<AudioId, AudioData*> AudiosData;
|
|
||||||
typedef QHash<DocumentId, DocumentData*> DocumentsData;
|
typedef QHash<DocumentId, DocumentData*> DocumentsData;
|
||||||
|
|
||||||
struct ReplyMarkup {
|
|
||||||
ReplyMarkup(int32 flags = 0) : flags(flags) {
|
|
||||||
}
|
|
||||||
typedef QList<QList<QString> > Commands;
|
|
||||||
Commands commands;
|
|
||||||
int32 flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LayeredWidget;
|
class LayeredWidget;
|
||||||
|
|
||||||
namespace App {
|
namespace App {
|
||||||
Application *app();
|
AppClass *app();
|
||||||
Window *wnd();
|
Window *wnd();
|
||||||
MainWidget *main();
|
MainWidget *main();
|
||||||
SettingsWidget *settings();
|
SettingsWidget *settings();
|
||||||
|
@ -68,7 +56,6 @@ namespace App {
|
||||||
ApiWrap *api();
|
ApiWrap *api();
|
||||||
|
|
||||||
void logOut();
|
void logOut();
|
||||||
bool loggedOut();
|
|
||||||
|
|
||||||
QString formatPhone(QString phone);
|
QString formatPhone(QString phone);
|
||||||
|
|
||||||
|
@ -85,6 +72,7 @@ namespace App {
|
||||||
void feedChatAdmins(const MTPDupdateChatAdmins &d, bool emitPeerUpdated = true);
|
void feedChatAdmins(const MTPDupdateChatAdmins &d, bool emitPeerUpdated = true);
|
||||||
void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d, bool emitPeerUpdated = true);
|
void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d, bool emitPeerUpdated = true);
|
||||||
bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached
|
bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached
|
||||||
|
void updateEditedMessage(const MTPDmessage &m);
|
||||||
void addSavedGif(DocumentData *doc);
|
void addSavedGif(DocumentData *doc);
|
||||||
void checkSavedGif(HistoryItem *item);
|
void checkSavedGif(HistoryItem *item);
|
||||||
void feedMsgs(const QVector<MTPMessage> &msgs, NewMessageType type);
|
void feedMsgs(const QVector<MTPMessage> &msgs, NewMessageType type);
|
||||||
|
@ -106,9 +94,6 @@ namespace App {
|
||||||
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
||||||
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = 0);
|
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = 0);
|
||||||
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = 0);
|
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = 0);
|
||||||
VideoData *feedVideo(const MTPDvideo &video, VideoData *convert = 0);
|
|
||||||
AudioData *feedAudio(const MTPaudio &audio, AudioData *convert = 0);
|
|
||||||
AudioData *feedAudio(const MTPDaudio &audio, AudioData *convert = 0);
|
|
||||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
|
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
|
||||||
DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = 0);
|
DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = 0);
|
||||||
DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = 0);
|
DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = 0);
|
||||||
|
@ -116,36 +101,57 @@ namespace App {
|
||||||
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = 0);
|
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = 0);
|
||||||
WebPageData *feedWebPage(const MTPWebPage &webpage);
|
WebPageData *feedWebPage(const MTPWebPage &webpage);
|
||||||
|
|
||||||
PeerData *peerLoaded(const PeerId &id);
|
PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded);
|
||||||
UserData *userLoaded(const PeerId &id);
|
inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||||
ChatData *chatLoaded(const PeerId &id);
|
return asUser(peer(id, restriction));
|
||||||
ChannelData *channelLoaded(const PeerId &id);
|
}
|
||||||
UserData *userLoaded(int32 user);
|
inline ChatData *chat(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||||
ChatData *chatLoaded(int32 chat);
|
return asChat(peer(id, restriction));
|
||||||
ChannelData *channelLoaded(int32 channel);
|
}
|
||||||
|
inline ChannelData *channel(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||||
|
return asChannel(peer(id, restriction));
|
||||||
|
}
|
||||||
|
inline UserData *user(UserId userId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||||
|
return asUser(peer(peerFromUser(userId), restriction));
|
||||||
|
}
|
||||||
|
inline ChatData *chat(ChatId chatId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||||
|
return asChat(peer(peerFromChat(chatId), restriction));
|
||||||
|
}
|
||||||
|
inline ChannelData *channel(ChannelId channelId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||||
|
return asChannel(peer(peerFromChannel(channelId), restriction));
|
||||||
|
}
|
||||||
|
inline PeerData *peerLoaded(const PeerId &id) {
|
||||||
|
return peer(id, PeerData::FullLoaded);
|
||||||
|
}
|
||||||
|
inline UserData *userLoaded(const PeerId &id) {
|
||||||
|
return user(id, PeerData::FullLoaded);
|
||||||
|
}
|
||||||
|
inline ChatData *chatLoaded(const PeerId &id) {
|
||||||
|
return chat(id, PeerData::FullLoaded);
|
||||||
|
}
|
||||||
|
inline ChannelData *channelLoaded(const PeerId &id) {
|
||||||
|
return channel(id, PeerData::FullLoaded);
|
||||||
|
}
|
||||||
|
inline UserData *userLoaded(UserId userId) {
|
||||||
|
return user(userId, PeerData::FullLoaded);
|
||||||
|
}
|
||||||
|
inline ChatData *chatLoaded(ChatId chatId) {
|
||||||
|
return chat(chatId, PeerData::FullLoaded);
|
||||||
|
}
|
||||||
|
inline ChannelData *channelLoaded(ChannelId channelId) {
|
||||||
|
return channel(channelId, PeerData::FullLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
PeerData *peer(const PeerId &id);
|
|
||||||
UserData *user(const PeerId &id);
|
|
||||||
ChatData *chat(const PeerId &id);
|
|
||||||
ChannelData *channel(const PeerId &id);
|
|
||||||
UserData *user(int32 user_id);
|
|
||||||
ChatData *chat(int32 chat_id);
|
|
||||||
ChannelData *channel(int32 channel_id);
|
|
||||||
UserData *self();
|
UserData *self();
|
||||||
PeerData *peerByName(const QString &username);
|
PeerData *peerByName(const QString &username);
|
||||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||||
PhotoData *photo(const PhotoId &photo);
|
PhotoData *photo(const PhotoId &photo);
|
||||||
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
|
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
|
||||||
VideoData *video(const VideoId &video);
|
|
||||||
VideoData *videoSet(const VideoId &video, VideoData *convert, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size);
|
|
||||||
AudioData *audio(const AudioId &audio);
|
|
||||||
AudioData *audioSet(const AudioId &audio, AudioData *convert, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size);
|
|
||||||
DocumentData *document(const DocumentId &document);
|
DocumentData *document(const DocumentId &document);
|
||||||
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
|
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
|
||||||
WebPageData *webPage(const WebPageId &webPage);
|
WebPageData *webPage(const WebPageId &webPage);
|
||||||
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill);
|
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill);
|
||||||
ImageLinkData *imageLink(const QString &imageLink);
|
LocationData *location(const LocationCoords &coords);
|
||||||
ImageLinkData *imageLinkSet(const QString &imageLink, ImageLinkType type, const QString &url);
|
|
||||||
void forgetMedia();
|
void forgetMedia();
|
||||||
|
|
||||||
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
|
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
|
||||||
|
@ -155,16 +161,27 @@ namespace App {
|
||||||
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead);
|
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead);
|
||||||
History *historyLoaded(const PeerId &peer);
|
History *historyLoaded(const PeerId &peer);
|
||||||
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
||||||
|
inline History *history(const PeerData *peer) {
|
||||||
|
t_assert(peer != nullptr);
|
||||||
|
return history(peer->id);
|
||||||
|
}
|
||||||
|
inline History *historyLoaded(const PeerData *peer) {
|
||||||
|
return peer ? historyLoaded(peer->id) : nullptr;
|
||||||
|
}
|
||||||
|
inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) {
|
||||||
|
return histItemById(channel ? peerToChannel(channel->id) : 0, itemId);
|
||||||
|
}
|
||||||
inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
||||||
return histItemById(msgId.channel, msgId.msg);
|
return histItemById(msgId.channel, msgId.msg);
|
||||||
}
|
}
|
||||||
void historyRegItem(HistoryItem *item);
|
void historyRegItem(HistoryItem *item);
|
||||||
void historyItemDetached(HistoryItem *item);
|
void historyItemDetached(HistoryItem *item);
|
||||||
void historyUnregItem(HistoryItem *item);
|
void historyUnregItem(HistoryItem *item);
|
||||||
|
void historyUpdateDependent(HistoryItem *item);
|
||||||
void historyClearMsgs();
|
void historyClearMsgs();
|
||||||
void historyClearItems();
|
void historyClearItems();
|
||||||
void historyRegReply(HistoryReply *reply, HistoryItem *to);
|
void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency);
|
||||||
void historyUnregReply(HistoryReply *reply, HistoryItem *to);
|
void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency);
|
||||||
|
|
||||||
void historyRegRandom(uint64 randomId, const FullMsgId &itemId);
|
void historyRegRandom(uint64 randomId, const FullMsgId &itemId);
|
||||||
void historyUnregRandom(uint64 randomId);
|
void historyUnregRandom(uint64 randomId);
|
||||||
|
@ -202,9 +219,15 @@ namespace App {
|
||||||
|
|
||||||
bool isValidPhone(QString phone);
|
bool isValidPhone(QString phone);
|
||||||
|
|
||||||
|
enum LaunchState {
|
||||||
|
Launched = 0,
|
||||||
|
QuitRequested = 1,
|
||||||
|
QuitProcessed = 2,
|
||||||
|
};
|
||||||
void quit();
|
void quit();
|
||||||
bool quiting();
|
bool quitting();
|
||||||
void setQuiting();
|
LaunchState launchState();
|
||||||
|
void setLaunchState(LaunchState state);
|
||||||
|
|
||||||
QImage readImage(QByteArray data, QByteArray *format = 0, bool opaque = true, bool *animated = 0);
|
QImage readImage(QByteArray data, QByteArray *format = 0, bool opaque = true, bool *animated = 0);
|
||||||
QImage readImage(const QString &file, QByteArray *format = 0, bool opaque = true, bool *animated = 0, QByteArray *content = 0);
|
QImage readImage(const QString &file, QByteArray *format = 0, bool opaque = true, bool *animated = 0, QByteArray *content = 0);
|
||||||
|
@ -214,16 +237,6 @@ namespace App {
|
||||||
const PhotoItems &photoItems();
|
const PhotoItems &photoItems();
|
||||||
const PhotosData &photosData();
|
const PhotosData &photosData();
|
||||||
|
|
||||||
void regVideoItem(VideoData *data, HistoryItem *item);
|
|
||||||
void unregVideoItem(VideoData *data, HistoryItem *item);
|
|
||||||
const VideoItems &videoItems();
|
|
||||||
const VideosData &videosData();
|
|
||||||
|
|
||||||
void regAudioItem(AudioData *data, HistoryItem *item);
|
|
||||||
void unregAudioItem(AudioData*data, HistoryItem *item);
|
|
||||||
const AudioItems &audioItems();
|
|
||||||
const AudiosData &audiosData();
|
|
||||||
|
|
||||||
void regDocumentItem(DocumentData *data, HistoryItem *item);
|
void regDocumentItem(DocumentData *data, HistoryItem *item);
|
||||||
void unregDocumentItem(DocumentData *data, HistoryItem *item);
|
void unregDocumentItem(DocumentData *data, HistoryItem *item);
|
||||||
const DocumentItems &documentItems();
|
const DocumentItems &documentItems();
|
||||||
|
@ -246,16 +259,10 @@ namespace App {
|
||||||
void unregMuted(PeerData *peer);
|
void unregMuted(PeerData *peer);
|
||||||
void updateMuted();
|
void updateMuted();
|
||||||
|
|
||||||
void regInlineResultLoader(FileLoader *loader, InlineResult *result);
|
|
||||||
void unregInlineResultLoader(FileLoader *loader);
|
|
||||||
InlineResult *inlineResultFromLoader(FileLoader *loader);
|
|
||||||
|
|
||||||
void feedReplyMarkup(ChannelId channelId, MsgId msgId, const MTPReplyMarkup &markup);
|
|
||||||
void clearReplyMarkup(ChannelId channelId, MsgId msgId);
|
|
||||||
const ReplyMarkup &replyMarkup(ChannelId channelId, MsgId msgId);
|
|
||||||
|
|
||||||
void setProxySettings(QNetworkAccessManager &manager);
|
void setProxySettings(QNetworkAccessManager &manager);
|
||||||
|
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
QNetworkProxy getHttpProxySettings();
|
QNetworkProxy getHttpProxySettings();
|
||||||
|
#endif
|
||||||
void setProxySettings(QTcpSocket &socket);
|
void setProxySettings(QTcpSocket &socket);
|
||||||
|
|
||||||
QImage **cornersMask();
|
QImage **cornersMask();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,35 +16,57 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QtNetwork/QLocalSocket>
|
|
||||||
#include <QtNetwork/QLocalServer>
|
|
||||||
#include <QtNetwork/QNetworkReply>
|
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "pspecific.h"
|
#include "pspecific.h"
|
||||||
|
|
||||||
class MainWidget;
|
class UpdateChecker;
|
||||||
class FileUploader;
|
class Application : public QApplication {
|
||||||
class Translator;
|
|
||||||
class UpdateDownloader;
|
|
||||||
|
|
||||||
class Application : public PsApplication, public RPCSender {
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Application(int &argc, char **argv);
|
Application(int &argc, char **argv);
|
||||||
~Application();
|
|
||||||
|
|
||||||
static Application *app();
|
// Single instance application
|
||||||
static Window *wnd();
|
public slots:
|
||||||
static QString language();
|
|
||||||
static int32 languageId();
|
void socketConnected();
|
||||||
static MainWidget *main();
|
void socketError(QLocalSocket::LocalSocketError e);
|
||||||
|
void socketDisconnected();
|
||||||
|
void socketWritten(qint64 bytes);
|
||||||
|
void socketReading();
|
||||||
|
void newInstanceConnected();
|
||||||
|
|
||||||
|
void readClients();
|
||||||
|
void removeClients();
|
||||||
|
|
||||||
|
void startApplication(); // will be done in exec()
|
||||||
|
void closeApplication(); // will be done in aboutToQuit()
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
|
||||||
|
typedef QList<LocalClient> LocalClients;
|
||||||
|
|
||||||
|
QString _localServerName, _localSocketReadData;
|
||||||
|
QLocalServer _localServer;
|
||||||
|
QLocalSocket _localSocket;
|
||||||
|
LocalClients _localClients;
|
||||||
|
bool _secondInstance;
|
||||||
|
|
||||||
|
void singleInstanceChecked();
|
||||||
|
|
||||||
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
|
||||||
|
// Autoupdating
|
||||||
|
public:
|
||||||
|
|
||||||
|
void startUpdateCheck(bool forceWait);
|
||||||
|
void stopUpdate();
|
||||||
|
|
||||||
enum UpdatingState {
|
enum UpdatingState {
|
||||||
UpdatingNone,
|
UpdatingNone,
|
||||||
|
@ -52,11 +74,87 @@ public:
|
||||||
UpdatingReady,
|
UpdatingReady,
|
||||||
};
|
};
|
||||||
UpdatingState updatingState();
|
UpdatingState updatingState();
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
int32 updatingSize();
|
int32 updatingSize();
|
||||||
int32 updatingReady();
|
int32 updatingReady();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void updateChecking();
|
||||||
|
void updateLatest();
|
||||||
|
void updateProgress(qint64 ready, qint64 total);
|
||||||
|
void updateReady();
|
||||||
|
void updateFailed();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void updateCheck();
|
||||||
|
|
||||||
|
void updateGotCurrent();
|
||||||
|
void updateFailedCurrent(QNetworkReply::NetworkError e);
|
||||||
|
|
||||||
|
void onUpdateReady();
|
||||||
|
void onUpdateFailed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SingleTimer _updateCheckTimer;
|
||||||
|
QNetworkReply *_updateReply;
|
||||||
|
QNetworkAccessManager _updateManager;
|
||||||
|
QThread *_updateThread;
|
||||||
|
UpdateChecker *_updateChecker;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Sandbox {
|
||||||
|
|
||||||
|
QRect availableGeometry();
|
||||||
|
QRect screenGeometry(const QPoint &p);
|
||||||
|
void setActiveWindow(QWidget *window);
|
||||||
|
bool isSavingSession();
|
||||||
|
|
||||||
|
void installEventFilter(QObject *filter);
|
||||||
|
|
||||||
|
void execExternal(const QString &cmd);
|
||||||
|
|
||||||
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
|
||||||
|
void startUpdateCheck();
|
||||||
void stopUpdate();
|
void stopUpdate();
|
||||||
#endif
|
|
||||||
|
Application::UpdatingState updatingState();
|
||||||
|
int32 updatingSize();
|
||||||
|
int32 updatingReady();
|
||||||
|
|
||||||
|
void updateChecking();
|
||||||
|
void updateLatest();
|
||||||
|
void updateProgress(qint64 ready, qint64 total);
|
||||||
|
void updateFailed();
|
||||||
|
void updateReady();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void connect(const char *signal, QObject *object, const char *method);
|
||||||
|
|
||||||
|
void launch();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWidget;
|
||||||
|
class FileUploader;
|
||||||
|
class Translator;
|
||||||
|
|
||||||
|
class AppClass : public QObject, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AppClass();
|
||||||
|
~AppClass();
|
||||||
|
|
||||||
|
static AppClass *app();
|
||||||
|
static Window *wnd();
|
||||||
|
static MainWidget *main();
|
||||||
|
|
||||||
FileUploader *uploader();
|
FileUploader *uploader();
|
||||||
void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId);
|
void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId);
|
||||||
|
@ -85,14 +183,6 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
void updateChecking();
|
|
||||||
void updateLatest();
|
|
||||||
void updateDownloading(qint64 ready, qint64 total);
|
|
||||||
void updateReady();
|
|
||||||
void updateFailed();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void peerPhotoDone(PeerId peer);
|
void peerPhotoDone(PeerId peer);
|
||||||
void peerPhotoFail(PeerId peer);
|
void peerPhotoFail(PeerId peer);
|
||||||
|
|
||||||
|
@ -100,31 +190,9 @@ signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
void startUpdateCheck(bool forceWait = false);
|
|
||||||
#endif
|
|
||||||
void socketConnected();
|
|
||||||
void socketError(QLocalSocket::LocalSocketError e);
|
|
||||||
void socketDisconnected();
|
|
||||||
void socketWritten(qint64 bytes);
|
|
||||||
void socketReading();
|
|
||||||
void newInstanceConnected();
|
|
||||||
void closeApplication();
|
|
||||||
|
|
||||||
void doMtpUnpause();
|
void doMtpUnpause();
|
||||||
|
|
||||||
void readClients();
|
void photoUpdated(const FullMsgId &msgId, bool silent, const MTPInputFile &file);
|
||||||
void removeClients();
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
void updateGotCurrent();
|
|
||||||
void updateFailedCurrent(QNetworkReply::NetworkError e);
|
|
||||||
|
|
||||||
void onUpdateReady();
|
|
||||||
void onUpdateFailed();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void photoUpdated(const FullMsgId &msgId, const MTPInputFile &file);
|
|
||||||
|
|
||||||
void onSwitchDebugMode();
|
void onSwitchDebugMode();
|
||||||
void onSwitchTestMode();
|
void onSwitchTestMode();
|
||||||
|
@ -132,6 +200,8 @@ public slots:
|
||||||
void killDownloadSessions();
|
void killDownloadSessions();
|
||||||
void onAppStateChanged(Qt::ApplicationState state);
|
void onAppStateChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
|
void call_handleHistoryUpdate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QMap<FullMsgId, PeerId> photoUpdates;
|
QMap<FullMsgId, PeerId> photoUpdates;
|
||||||
|
@ -139,35 +209,12 @@ private:
|
||||||
QMap<int32, uint64> killDownloadSessionTimes;
|
QMap<int32, uint64> killDownloadSessionTimes;
|
||||||
SingleTimer killDownloadSessionsTimer;
|
SingleTimer killDownloadSessionsTimer;
|
||||||
|
|
||||||
void startApp();
|
uint64 _lastActionTime;
|
||||||
|
|
||||||
typedef QPair<QLocalSocket*, QByteArray> ClientSocket;
|
Window *_window;
|
||||||
typedef QVector<ClientSocket> ClientSockets;
|
FileUploader *_uploader;
|
||||||
|
Translator *_translator;
|
||||||
QString serverName;
|
|
||||||
QLocalSocket socket;
|
|
||||||
QString socketRead;
|
|
||||||
QLocalServer server;
|
|
||||||
ClientSockets clients;
|
|
||||||
bool closing;
|
|
||||||
|
|
||||||
uint64 lastActionTime;
|
|
||||||
|
|
||||||
void execExternal(const QString &cmd);
|
|
||||||
|
|
||||||
Window *window;
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
mtpRequestId updateRequestId;
|
|
||||||
QNetworkAccessManager updateManager;
|
|
||||||
QNetworkReply *updateReply;
|
|
||||||
SingleTimer updateCheckTimer;
|
|
||||||
QThread *updateThread;
|
|
||||||
UpdateDownloader *updateDownloader;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SingleTimer _mtpUnpauseTimer;
|
SingleTimer _mtpUnpauseTimer;
|
||||||
|
|
||||||
Translator *_translator;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 178 KiB |
Binary file not shown.
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 243 KiB |
File diff suppressed because it is too large
Load diff
|
@ -16,11 +16,11 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "types.h"
|
#include "basic_types.h"
|
||||||
|
|
||||||
void audioInit();
|
void audioInit();
|
||||||
bool audioWorks();
|
bool audioWorks();
|
||||||
|
@ -56,7 +56,7 @@ public:
|
||||||
void play(const AudioMsgId &audio, int64 position = 0);
|
void play(const AudioMsgId &audio, int64 position = 0);
|
||||||
void play(const SongMsgId &song, int64 position = 0);
|
void play(const SongMsgId &song, int64 position = 0);
|
||||||
void pauseresume(MediaOverviewType type, bool fast = false);
|
void pauseresume(MediaOverviewType type, bool fast = false);
|
||||||
void seek(int64 position); // type == OverviewDocuments
|
void seek(int64 position); // type == OverviewFiles
|
||||||
void stop(MediaOverviewType type);
|
void stop(MediaOverviewType type);
|
||||||
|
|
||||||
void stopAndClear();
|
void stopAndClear();
|
||||||
|
@ -201,8 +201,8 @@ signals:
|
||||||
void captureOnStart();
|
void captureOnStart();
|
||||||
void captureOnStop(bool needResult);
|
void captureOnStop(bool needResult);
|
||||||
|
|
||||||
void onDone(QByteArray data, qint32 samples);
|
void onDone(QByteArray data, VoiceWaveform waveform, qint32 samples);
|
||||||
void onUpdate(qint16 level, qint32 samples);
|
void onUpdate(quint16 level, qint32 samples);
|
||||||
void onError();
|
void onError();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -338,8 +338,8 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void error();
|
void error();
|
||||||
void update(qint16 level, qint32 samples);
|
void update(quint16 level, qint32 samples);
|
||||||
void done(QByteArray data, qint32 samples);
|
void done(QByteArray data, VoiceWaveform waveform, qint32 samples);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -360,3 +360,4 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat);
|
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat);
|
||||||
|
VoiceWaveform audioCountWaveform(const FileLocation &file, const QByteArray &data);
|
||||||
|
|
|
@ -16,13 +16,26 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "autoupdater.h"
|
||||||
|
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||||
|
#include <LzmaLib.h>
|
||||||
|
#else // Q_OS_WIN
|
||||||
|
#include <lzma.h>
|
||||||
|
#endif // else of Q_OS_WIN
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "pspecific.h"
|
#include "pspecific.h"
|
||||||
#include "autoupdater.h"
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
|
||||||
|
@ -34,7 +47,7 @@ typedef int VerInt;
|
||||||
typedef wchar_t VerChar;
|
typedef wchar_t VerChar;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UpdateDownloader::UpdateDownloader(QThread *thread, const QString &url) : reply(0), already(0), full(0) {
|
UpdateChecker::UpdateChecker(QThread *thread, const QString &url) : reply(0), already(0), full(0) {
|
||||||
updateUrl = url;
|
updateUrl = url;
|
||||||
moveToThread(thread);
|
moveToThread(thread);
|
||||||
manager.moveToThread(thread);
|
manager.moveToThread(thread);
|
||||||
|
@ -44,14 +57,14 @@ UpdateDownloader::UpdateDownloader(QThread *thread, const QString &url) : reply(
|
||||||
initOutput();
|
initOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::initOutput() {
|
void UpdateChecker::initOutput() {
|
||||||
QString fileName;
|
QString fileName;
|
||||||
QRegularExpressionMatch m = QRegularExpression(qsl("/([^/\\?]+)(\\?|$)")).match(updateUrl);
|
QRegularExpressionMatch m = QRegularExpression(qsl("/([^/\\?]+)(\\?|$)")).match(updateUrl);
|
||||||
if (m.hasMatch()) {
|
if (m.hasMatch()) {
|
||||||
fileName = m.captured(1).replace(QRegularExpression(qsl("[^a-zA-Z0-9_\\-]")), QString());
|
fileName = m.captured(1).replace(QRegularExpression(qsl("[^a-zA-Z0-9_\\-]")), QString());
|
||||||
}
|
}
|
||||||
if (fileName.isEmpty()) {
|
if (fileName.isEmpty()) {
|
||||||
fileName = qsl("tupdate-%1").arg(MTP::nonce<uint32>() % 1000000);
|
fileName = qsl("tupdate-%1").arg(rand_value<uint32>() % 1000000);
|
||||||
}
|
}
|
||||||
QString dirStr = cWorkingDir() + qsl("tupdates/");
|
QString dirStr = cWorkingDir() + qsl("tupdates/");
|
||||||
fileName = dirStr + fileName;
|
fileName = dirStr + fileName;
|
||||||
|
@ -99,11 +112,11 @@ void UpdateDownloader::initOutput() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::start() {
|
void UpdateChecker::start() {
|
||||||
sendRequest();
|
sendRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::sendRequest() {
|
void UpdateChecker::sendRequest() {
|
||||||
QNetworkRequest req(updateUrl);
|
QNetworkRequest req(updateUrl);
|
||||||
QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(already) + "-";
|
QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(already) + "-";
|
||||||
req.setRawHeader("Range", rangeHeaderValue);
|
req.setRawHeader("Range", rangeHeaderValue);
|
||||||
|
@ -115,7 +128,7 @@ void UpdateDownloader::sendRequest() {
|
||||||
connect(reply, SIGNAL(metaDataChanged()), this, SLOT(partMetaGot()));
|
connect(reply, SIGNAL(metaDataChanged()), this, SLOT(partMetaGot()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::partMetaGot() {
|
void UpdateChecker::partMetaGot() {
|
||||||
typedef QList<QNetworkReply::RawHeaderPair> Pairs;
|
typedef QList<QNetworkReply::RawHeaderPair> Pairs;
|
||||||
Pairs pairs = reply->rawHeaderPairs();
|
Pairs pairs = reply->rawHeaderPairs();
|
||||||
for (Pairs::iterator i = pairs.begin(), e = pairs.end(); i != e; ++i) {
|
for (Pairs::iterator i = pairs.begin(), e = pairs.end(); i != e; ++i) {
|
||||||
|
@ -126,23 +139,24 @@ void UpdateDownloader::partMetaGot() {
|
||||||
QMutexLocker lock(&mutex);
|
QMutexLocker lock(&mutex);
|
||||||
full = m.captured(1).toInt();
|
full = m.captured(1).toInt();
|
||||||
}
|
}
|
||||||
emit App::app()->updateDownloading(already, full);
|
|
||||||
|
Sandbox::updateProgress(already, full);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 UpdateDownloader::ready() {
|
int32 UpdateChecker::ready() {
|
||||||
QMutexLocker lock(&mutex);
|
QMutexLocker lock(&mutex);
|
||||||
return already;
|
return already;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 UpdateDownloader::size() {
|
int32 UpdateChecker::size() {
|
||||||
QMutexLocker lock(&mutex);
|
QMutexLocker lock(&mutex);
|
||||||
return full;
|
return full;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::partFinished(qint64 got, qint64 total) {
|
void UpdateChecker::partFinished(qint64 got, qint64 total) {
|
||||||
if (!reply) return;
|
if (!reply) return;
|
||||||
|
|
||||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||||
|
@ -179,11 +193,11 @@ void UpdateDownloader::partFinished(qint64 got, qint64 total) {
|
||||||
outputFile.close();
|
outputFile.close();
|
||||||
unpackUpdate();
|
unpackUpdate();
|
||||||
} else {
|
} else {
|
||||||
emit App::app()->updateDownloading(already, full);
|
Sandbox::updateProgress(already, full);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::partFailed(QNetworkReply::NetworkError e) {
|
void UpdateChecker::partFailed(QNetworkReply::NetworkError e) {
|
||||||
if (!reply) return;
|
if (!reply) return;
|
||||||
|
|
||||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||||
|
@ -198,15 +212,15 @@ void UpdateDownloader::partFailed(QNetworkReply::NetworkError e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG(("Update Error: failed to download part starting from %1, error %2").arg(already).arg(e));
|
LOG(("Update Error: failed to download part starting from %1, error %2").arg(already).arg(e));
|
||||||
emit App::app()->updateFailed();
|
Sandbox::updateFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::fatalFail() {
|
void UpdateChecker::fatalFail() {
|
||||||
clearAll();
|
clearAll();
|
||||||
emit App::app()->updateFailed();
|
Sandbox::updateFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDownloader::clearAll() {
|
void UpdateChecker::clearAll() {
|
||||||
psDeleteDir(cWorkingDir() + qsl("tupdates"));
|
psDeleteDir(cWorkingDir() + qsl("tupdates"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +239,7 @@ void UpdateDownloader::clearAll() {
|
||||||
// return QString::fromWCharArray(errMsg);
|
// return QString::fromWCharArray(errMsg);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void UpdateDownloader::unpackUpdate() {
|
void UpdateChecker::unpackUpdate() {
|
||||||
QByteArray packed;
|
QByteArray packed;
|
||||||
if (!outputFile.open(QIODevice::ReadOnly)) {
|
if (!outputFile.open(QIODevice::ReadOnly)) {
|
||||||
LOG(("Update Error: cant read updates file!"));
|
LOG(("Update Error: cant read updates file!"));
|
||||||
|
@ -465,10 +479,10 @@ void UpdateDownloader::unpackUpdate() {
|
||||||
}
|
}
|
||||||
outputFile.remove();
|
outputFile.remove();
|
||||||
|
|
||||||
emit App::app()->updateReady();
|
Sandbox::updateReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateDownloader::~UpdateDownloader() {
|
UpdateChecker::~UpdateChecker() {
|
||||||
delete reply;
|
delete reply;
|
||||||
reply = 0;
|
reply = 0;
|
||||||
}
|
}
|
||||||
|
@ -477,7 +491,7 @@ bool checkReadyUpdate() {
|
||||||
QString readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready"), readyPath = cWorkingDir() + qsl("tupdates/temp");
|
QString readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready"), readyPath = cWorkingDir() + qsl("tupdates/temp");
|
||||||
if (!QFile(readyFilePath).exists()) {
|
if (!QFile(readyFilePath).exists()) {
|
||||||
if (QDir(cWorkingDir() + qsl("tupdates/ready")).exists() || QDir(cWorkingDir() + qsl("tupdates/temp")).exists()) {
|
if (QDir(cWorkingDir() + qsl("tupdates/ready")).exists() || QDir(cWorkingDir() + qsl("tupdates/temp")).exists()) {
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -488,30 +502,30 @@ bool checkReadyUpdate() {
|
||||||
QFile fVersion(versionPath);
|
QFile fVersion(versionPath);
|
||||||
if (!fVersion.open(QIODevice::ReadOnly)) {
|
if (!fVersion.open(QIODevice::ReadOnly)) {
|
||||||
LOG(("Update Error: cant read version file '%1'").arg(versionPath));
|
LOG(("Update Error: cant read version file '%1'").arg(versionPath));
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
VerInt versionNum;
|
VerInt versionNum;
|
||||||
if (fVersion.read((char*)&versionNum, sizeof(VerInt)) != sizeof(VerInt)) {
|
if (fVersion.read((char*)&versionNum, sizeof(VerInt)) != sizeof(VerInt)) {
|
||||||
LOG(("Update Error: cant read version from file '%1'").arg(versionPath));
|
LOG(("Update Error: cant read version from file '%1'").arg(versionPath));
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (versionNum == 0x7FFFFFFF) { // beta version
|
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||||
quint64 betaVersion = 0;
|
quint64 betaVersion = 0;
|
||||||
if (fVersion.read((char*)&betaVersion, sizeof(quint64)) != sizeof(quint64)) {
|
if (fVersion.read((char*)&betaVersion, sizeof(quint64)) != sizeof(quint64)) {
|
||||||
LOG(("Update Error: cant read beta version from file '%1'").arg(versionPath));
|
LOG(("Update Error: cant read beta version from file '%1'").arg(versionPath));
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
||||||
LOG(("Update Error: cant install beta version %1 having beta version %2").arg(betaVersion).arg(cBetaVersion()));
|
LOG(("Update Error: cant install beta version %1 having beta version %2").arg(betaVersion).arg(cBetaVersion()));
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (versionNum <= AppVersion) {
|
} else if (versionNum <= AppVersion) {
|
||||||
LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
|
LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fVersion.close();
|
fVersion.close();
|
||||||
|
@ -530,11 +544,11 @@ bool checkReadyUpdate() {
|
||||||
if (!updater.exists()) {
|
if (!updater.exists()) {
|
||||||
QFileInfo current(curUpdater);
|
QFileInfo current(curUpdater);
|
||||||
if (!current.exists()) {
|
if (!current.exists()) {
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!QFile(current.absoluteFilePath()).copy(updater.absoluteFilePath())) {
|
if (!QFile(current.absoluteFilePath()).copy(updater.absoluteFilePath())) {
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,24 +559,24 @@ bool checkReadyUpdate() {
|
||||||
cSetWriteProtected(true);
|
cSetWriteProtected(true);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (DeleteFile(updater.absoluteFilePath().toStdWString().c_str()) == FALSE) {
|
if (DeleteFile(updater.absoluteFilePath().toStdWString().c_str()) == FALSE) {
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#elif defined Q_OS_MAC
|
#elif defined Q_OS_MAC
|
||||||
QDir().mkpath(QFileInfo(curUpdater).absolutePath());
|
QDir().mkpath(QFileInfo(curUpdater).absolutePath());
|
||||||
DEBUG_LOG(("Update Info: moving %1 to %2..").arg(updater.absoluteFilePath()).arg(curUpdater));
|
DEBUG_LOG(("Update Info: moving %1 to %2...").arg(updater.absoluteFilePath()).arg(curUpdater));
|
||||||
if (!objc_moveFile(updater.absoluteFilePath(), curUpdater)) {
|
if (!objc_moveFile(updater.absoluteFilePath(), curUpdater)) {
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#elif defined Q_OS_LINUX
|
#elif defined Q_OS_LINUX
|
||||||
if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) {
|
if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) {
|
||||||
UpdateDownloader::clearAll();
|
UpdateChecker::clearAll();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
#include <QtNetwork/QLocalServer>
|
#include <QtNetwork/QLocalServer>
|
||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
|
||||||
class UpdateDownloader : public QObject {
|
class UpdateChecker : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateDownloader(QThread *thread, const QString &url);
|
UpdateChecker(QThread *thread, const QString &url);
|
||||||
|
|
||||||
void unpackUpdate();
|
void unpackUpdate();
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public:
|
||||||
|
|
||||||
static void clearAll();
|
static void clearAll();
|
||||||
|
|
||||||
~UpdateDownloader();
|
~UpdateChecker();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -66,6 +66,11 @@ private:
|
||||||
|
|
||||||
bool checkReadyUpdate();
|
bool checkReadyUpdate();
|
||||||
|
|
||||||
|
#else
|
||||||
|
class UpdateChecker : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString countBetaVersionSignature(uint64 version);
|
QString countBetaVersionSignature(uint64 version);
|
||||||
|
|
|
@ -16,10 +16,20 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "basic_types.h"
|
||||||
|
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavformat/avformat.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
|
||||||
uint64 _SharedMemoryLocation[4] = { 0x00, 0x01, 0x02, 0x03 };
|
uint64 _SharedMemoryLocation[4] = { 0x00, 0x01, 0x02, 0x03 };
|
||||||
|
@ -35,6 +45,10 @@ uint64 _SharedMemoryLocation[4] = { 0x00, 0x01, 0x02, 0x03 };
|
||||||
|
|
||||||
// Base types compile-time check
|
// Base types compile-time check
|
||||||
|
|
||||||
|
#ifdef TDESKTOP_CUSTOM_NULLPTR
|
||||||
|
NullPointerClass nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
class _TypeSizeCheckerHelper {
|
class _TypeSizeCheckerHelper {
|
||||||
|
@ -106,8 +120,8 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 myunixtime() {
|
TimeId myunixtime() {
|
||||||
return (int32)time(NULL);
|
return (TimeId)time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unixtimeInit() {
|
void unixtimeInit() {
|
||||||
|
@ -135,19 +149,19 @@ void unixtimeSet(int32 serverTime, bool force) {
|
||||||
_initMsgIdConstants();
|
_initMsgIdConstants();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 unixtime() {
|
TimeId unixtime() {
|
||||||
int32 result = myunixtime();
|
TimeId result = myunixtime();
|
||||||
|
|
||||||
QReadLocker locker(&unixtimeLock);
|
QReadLocker locker(&unixtimeLock);
|
||||||
return result + unixtimeDelta;
|
return result + unixtimeDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 fromServerTime(const MTPint &serverTime) {
|
TimeId fromServerTime(const MTPint &serverTime) {
|
||||||
QReadLocker locker(&unixtimeLock);
|
QReadLocker locker(&unixtimeLock);
|
||||||
return serverTime.v - unixtimeDelta;
|
return serverTime.v - unixtimeDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTPint toServerTime(const int32 &clientTime) {
|
MTPint toServerTime(const TimeId &clientTime) {
|
||||||
QReadLocker locker(&unixtimeLock);
|
QReadLocker locker(&unixtimeLock);
|
||||||
return MTP_int(clientTime + unixtimeDelta);
|
return MTP_int(clientTime + unixtimeDelta);
|
||||||
}
|
}
|
||||||
|
@ -187,6 +201,32 @@ namespace {
|
||||||
delete l;
|
delete l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _ffmpegLockManager(void **mutex, AVLockOp op) {
|
||||||
|
switch (op) {
|
||||||
|
case AV_LOCK_CREATE: {
|
||||||
|
t_assert(*mutex == 0);
|
||||||
|
*mutex = reinterpret_cast<void*>(new QMutex());
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AV_LOCK_OBTAIN: {
|
||||||
|
t_assert(*mutex != 0);
|
||||||
|
reinterpret_cast<QMutex*>(*mutex)->lock();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AV_LOCK_RELEASE: {
|
||||||
|
t_assert(*mutex != 0);
|
||||||
|
reinterpret_cast<QMutex*>(*mutex)->unlock();
|
||||||
|
}; break;
|
||||||
|
|
||||||
|
case AV_LOCK_DESTROY: {
|
||||||
|
t_assert(*mutex != 0);
|
||||||
|
delete reinterpret_cast<QMutex*>(*mutex);
|
||||||
|
*mutex = 0;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
float64 _msFreq;
|
float64 _msFreq;
|
||||||
float64 _msgIdCoef;
|
float64 _msgIdCoef;
|
||||||
int64 _msStart = 0, _msAddToMsStart = 0, _msAddToUnixtime = 0;
|
int64 _msStart = 0, _msAddToMsStart = 0, _msAddToUnixtime = 0;
|
||||||
|
@ -238,36 +278,51 @@ namespace {
|
||||||
_MsStarter _msStarter;
|
_MsStarter _msStarter;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitOpenSSL::InitOpenSSL() {
|
namespace ThirdParty {
|
||||||
if (!RAND_status()) { // should be always inited in all modern OS
|
|
||||||
char buf[16];
|
void start() {
|
||||||
memcpy(buf, &_msStart, 8);
|
PlatformSpecific::ThirdParty::start();
|
||||||
memcpy(buf + 8, &_msFreq, 8);
|
|
||||||
uchar sha256Buffer[32];
|
if (!RAND_status()) { // should be always inited in all modern OS
|
||||||
RAND_seed(hashSha256(buf, 16, sha256Buffer), 32);
|
char buf[16];
|
||||||
if (!RAND_status()) {
|
memcpy(buf, &_msStart, 8);
|
||||||
LOG(("MTP Error: Could not init OpenSSL rand, RAND_status() is 0.."));
|
memcpy(buf + 8, &_msFreq, 8);
|
||||||
|
uchar sha256Buffer[32];
|
||||||
|
RAND_seed(hashSha256(buf, 16, sha256Buffer), 32);
|
||||||
|
if (!RAND_status()) {
|
||||||
|
LOG(("MTP Error: Could not init OpenSSL rand, RAND_status() is 0..."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 numLocks = CRYPTO_num_locks();
|
||||||
|
if (numLocks) {
|
||||||
|
_sslLocks = new QMutex[numLocks];
|
||||||
|
CRYPTO_set_locking_callback(_sslLockingCallback);
|
||||||
|
} else {
|
||||||
|
LOG(("MTP Error: Could not init OpenSSL threads, CRYPTO_num_locks() returned zero!"));
|
||||||
|
}
|
||||||
|
CRYPTO_THREADID_set_callback(_sslThreadId);
|
||||||
|
CRYPTO_set_dynlock_create_callback(_sslCreateFunction);
|
||||||
|
CRYPTO_set_dynlock_lock_callback(_sslLockFunction);
|
||||||
|
CRYPTO_set_dynlock_destroy_callback(_sslDestroyFunction);
|
||||||
|
|
||||||
|
av_register_all();
|
||||||
|
avcodec_register_all();
|
||||||
|
|
||||||
|
av_lockmgr_register(_ffmpegLockManager);
|
||||||
|
|
||||||
|
_sslInited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 numLocks = CRYPTO_num_locks();
|
void finish() {
|
||||||
if (numLocks) {
|
av_lockmgr_register(0);
|
||||||
_sslLocks = new QMutex[numLocks];
|
|
||||||
CRYPTO_set_locking_callback(_sslLockingCallback);
|
delete[] _sslLocks;
|
||||||
} else {
|
_sslLocks = 0;
|
||||||
LOG(("MTP Error: Could not init OpenSSL threads, CRYPTO_num_locks() returned zero!"));
|
|
||||||
|
PlatformSpecific::ThirdParty::finish();
|
||||||
}
|
}
|
||||||
CRYPTO_THREADID_set_callback(_sslThreadId);
|
|
||||||
CRYPTO_set_dynlock_create_callback(_sslCreateFunction);
|
|
||||||
CRYPTO_set_dynlock_lock_callback(_sslLockFunction);
|
|
||||||
CRYPTO_set_dynlock_destroy_callback(_sslDestroyFunction);
|
|
||||||
|
|
||||||
_sslInited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitOpenSSL::~InitOpenSSL() {
|
|
||||||
delete[] _sslLocks;
|
|
||||||
_sslLocks = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkms() {
|
bool checkms() {
|
||||||
|
@ -640,10 +695,7 @@ char *hashMd5Hex(const int32 *hashmd5, void *dest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void memset_rand(void *data, uint32 len) {
|
void memset_rand(void *data, uint32 len) {
|
||||||
if (!_sslInited) {
|
t_assert(_sslInited);
|
||||||
LOG(("Critical Error: memset_rand() called before OpenSSL init!"));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
RAND_bytes((uchar*)data, len);
|
RAND_bytes((uchar*)data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,8 +829,7 @@ QString translitRusEng(const QString &rus) {
|
||||||
result.reserve(rus.size() * 2);
|
result.reserve(rus.size() * 2);
|
||||||
|
|
||||||
int32 toSkip = 0;
|
int32 toSkip = 0;
|
||||||
for (QString::const_iterator i = rus.cbegin(), e = rus.cend(); i != e;) {
|
for (QString::const_iterator i = rus.cbegin(), e = rus.cend(); i != e; i += toSkip) {
|
||||||
i += toSkip;
|
|
||||||
result += translitLetterRusEng(*i, (i + 1 == e) ? ' ' : *(i + 1), toSkip);
|
result += translitLetterRusEng(*i, (i + 1 == e) ? ' ' : *(i + 1), toSkip);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -982,3 +1033,33 @@ MimeType mimeTypeForData(const QByteArray &data) {
|
||||||
}
|
}
|
||||||
return MimeType(QMimeDatabase().mimeTypeForData(data));
|
return MimeType(QMimeDatabase().mimeTypeForData(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ComposerMetadatasMap {
|
||||||
|
QMap<uint64, ComposerMetadata*> data;
|
||||||
|
~ComposerMetadatasMap() {
|
||||||
|
for_const (const ComposerMetadata *p, data) {
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ComposerMetadata *GetComposerMetadata(uint64 mask) {
|
||||||
|
static ComposerMetadatasMap ComposerMetadatas;
|
||||||
|
static QMutex ComposerMetadatasMutex;
|
||||||
|
|
||||||
|
QMutexLocker lock(&ComposerMetadatasMutex);
|
||||||
|
auto i = ComposerMetadatas.data.constFind(mask);
|
||||||
|
if (i == ComposerMetadatas.data.cend()) {
|
||||||
|
ComposerMetadata *meta = new ComposerMetadata(mask);
|
||||||
|
t_assert(meta != nullptr);
|
||||||
|
|
||||||
|
i = ComposerMetadatas.data.insert(mask, meta);
|
||||||
|
}
|
||||||
|
return i.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ComposerMetadata *Composer::ZeroComposerMetadata = GetComposerMetadata(0);
|
||||||
|
|
||||||
|
ComponentWrapStruct ComponentWraps[64];
|
||||||
|
|
||||||
|
QAtomicInt ComponentIndexLast;
|
1362
Telegram/SourceFiles/basic_types.h
Normal file
1362
Telegram/SourceFiles/basic_types.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -44,6 +44,8 @@ AboutBox::AboutBox() : AbstractBox(st::aboutWidth)
|
||||||
connect(&_done, SIGNAL(clicked()), this, SLOT(onClose()));
|
connect(&_done, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
|
setAcceptDrops(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutBox::hideAll() {
|
void AboutBox::hideAll() {
|
||||||
|
@ -82,7 +84,7 @@ void AboutBox::onVersion() {
|
||||||
}
|
}
|
||||||
url = url.arg(qsl("tbeta%1_%2").arg(cRealBetaVersion()).arg(countBetaVersionSignature(cRealBetaVersion())));
|
url = url.arg(qsl("tbeta%1_%2").arg(cRealBetaVersion()).arg(countBetaVersionSignature(cRealBetaVersion())));
|
||||||
|
|
||||||
App::app()->clipboard()->setText(url);
|
Application::clipboard()->setText(url);
|
||||||
|
|
||||||
Ui::showLayer(new InformBox("The link to the current private beta version of Telegram Desktop was copied to the clipboard."));
|
Ui::showLayer(new InformBox("The link to the current private beta version of Telegram Desktop was copied to the clipboard."));
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,10 +107,39 @@ void AboutBox::paintEvent(QPaintEvent *e) {
|
||||||
paintTitle(p, qsl("Telegram Desktop"));
|
paintTitle(p, qsl("Telegram Desktop"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||||
|
QString _getCrashReportFile(const QMimeData *m) {
|
||||||
|
if (!m || m->urls().size() != 1) return QString();
|
||||||
|
|
||||||
|
QString file(m->urls().at(0).toLocalFile());
|
||||||
|
if (file.startsWith(qsl("/.file/id="))) file = psConvertFileUrl(file);
|
||||||
|
|
||||||
|
return file.endsWith(qstr(".telegramcrash"), Qt::CaseInsensitive) ? file : QString();
|
||||||
|
}
|
||||||
|
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||||
|
|
||||||
|
void AboutBox::dragEnterEvent(QDragEnterEvent *e) {
|
||||||
|
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||||
|
if (!_getCrashReportFile(e->mimeData()).isEmpty()) {
|
||||||
|
e->setDropAction(Qt::CopyAction);
|
||||||
|
e->accept();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void AboutBox::dropEvent(QDropEvent *e) {
|
||||||
|
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||||
|
if (!_getCrashReportFile(e->mimeData()).isEmpty()) {
|
||||||
|
e->acceptProposedAction();
|
||||||
|
showCrashReportWindow(_getCrashReportFile(e->mimeData()));
|
||||||
|
}
|
||||||
|
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
|
||||||
|
}
|
||||||
|
|
||||||
QString telegramFaqLink() {
|
QString telegramFaqLink() {
|
||||||
QString result = qsl("https://telegram.org/faq");
|
QString result = qsl("https://telegram.org/faq");
|
||||||
if (cLang() > languageDefault && cLang() < languageCount) {
|
if (cLang() > languageDefault && cLang() < languageCount) {
|
||||||
const char *code = LanguageCodes[cLang()];
|
const char *code = LanguageCodes[cLang()].c_str();
|
||||||
if (qstr("de") == code || qstr("es") == code || qstr("it") == code || qstr("ko") == code) {
|
if (qstr("de") == code || qstr("es") == code || qstr("it") == code || qstr("ko") == code) {
|
||||||
result += qsl("/") + code;
|
result += qsl("/") + code;
|
||||||
} else if (qstr("pt_BR") == code) {
|
} else if (qstr("pt_BR") == code) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ public:
|
||||||
void keyPressEvent(QKeyEvent *e);
|
void keyPressEvent(QKeyEvent *e);
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
|
|
||||||
|
void dragEnterEvent(QDragEnterEvent *e);
|
||||||
|
void dropEvent(QDropEvent *e);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onVersion();
|
void onVersion();
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -178,6 +178,14 @@ void AbstractBox::resizeMaxHeight(int32 newWidth, int32 maxHeight) {
|
||||||
_maxHeight = maxHeight;
|
_maxHeight = maxHeight;
|
||||||
resize(newWidth, countHeight());
|
resize(newWidth, countHeight());
|
||||||
if (parentWidget()) {
|
if (parentWidget()) {
|
||||||
|
QRect r = geometry();
|
||||||
|
int32 parenth = parentWidget()->height();
|
||||||
|
if (r.top() + r.height() + st::boxVerticalMargin > parenth) {
|
||||||
|
int32 newTop = qMax(parenth - int(st::boxVerticalMargin) - r.height(), (parenth - r.height()) / 2);
|
||||||
|
if (newTop != r.top()) {
|
||||||
|
move(r.left(), newTop);
|
||||||
|
}
|
||||||
|
}
|
||||||
parentWidget()->update(geometry().united(g).marginsAdded(QMargins(st::boxShadow.pxWidth(), st::boxShadow.pxHeight(), st::boxShadow.pxWidth(), st::boxShadow.pxHeight())));
|
parentWidget()->update(geometry().united(g).marginsAdded(QMargins(st::boxShadow.pxWidth(), st::boxShadow.pxHeight(), st::boxShadow.pxWidth(), st::boxShadow.pxHeight())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -188,11 +188,11 @@ void AddContactBox::onSave() {
|
||||||
}
|
}
|
||||||
_sentName = firstName;
|
_sentName = firstName;
|
||||||
if (_user) {
|
if (_user) {
|
||||||
_contactId = MTP::nonce<uint64>();
|
_contactId = rand_value<uint64>();
|
||||||
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_user->phone), MTP_string(firstName), MTP_string(lastName)));
|
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_user->phone), MTP_string(firstName), MTP_string(lastName)));
|
||||||
_addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector<MTPInputContact>(v), MTP_bool(false)), rpcDone(&AddContactBox::onSaveUserDone), rpcFail(&AddContactBox::onSaveUserFail));
|
_addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector<MTPInputContact>(v), MTP_bool(false)), rpcDone(&AddContactBox::onSaveUserDone), rpcFail(&AddContactBox::onSaveUserFail));
|
||||||
} else {
|
} else {
|
||||||
_contactId = MTP::nonce<uint64>();
|
_contactId = rand_value<uint64>();
|
||||||
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(phone), MTP_string(firstName), MTP_string(lastName)));
|
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(phone), MTP_string(firstName), MTP_string(lastName)));
|
||||||
_addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector<MTPInputContact>(v), MTP_bool(false)), rpcDone(&AddContactBox::onImportDone));
|
_addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector<MTPInputContact>(v), MTP_bool(false)), rpcDone(&AddContactBox::onImportDone));
|
||||||
}
|
}
|
||||||
|
@ -224,18 +224,15 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) {
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
|
|
||||||
const QVector<MTPImportedContact> &v(d.vimported.c_vector().v);
|
const QVector<MTPImportedContact> &v(d.vimported.c_vector().v);
|
||||||
int32 uid = 0;
|
UserData *user = nullptr;
|
||||||
if (!v.isEmpty()) {
|
if (!v.isEmpty()) {
|
||||||
const MTPDimportedContact &c(v.front().c_importedContact());
|
const MTPDimportedContact &c(v.front().c_importedContact());
|
||||||
if (c.vclient_id.v != _contactId) return;
|
if (c.vclient_id.v != _contactId) return;
|
||||||
|
|
||||||
uid = c.vuser_id.v;
|
user = App::userLoaded(c.vuser_id.v);
|
||||||
if (uid && !App::userLoaded(uid)) {
|
|
||||||
uid = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (uid) {
|
if (user) {
|
||||||
Notify::userIsContactChanged(App::userLoaded(peerFromUser(uid)), true);
|
Notify::userIsContactChanged(user, true);
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
} else {
|
} else {
|
||||||
_save.hide();
|
_save.hide();
|
||||||
|
@ -275,7 +272,7 @@ NewGroupBox::NewGroupBox() : AbstractBox(),
|
||||||
_group(this, qsl("group_type"), 0, lang(lng_create_group_title), true),
|
_group(this, qsl("group_type"), 0, lang(lng_create_group_title), true),
|
||||||
_channel(this, qsl("group_type"), 1, lang(lng_create_channel_title)),
|
_channel(this, qsl("group_type"), 1, lang(lng_create_channel_title)),
|
||||||
_aboutGroupWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x()),
|
_aboutGroupWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x()),
|
||||||
_aboutGroup(st::normalFont, lng_create_group_about(lt_count, cMaxGroupCount()), _defaultOptions, _aboutGroupWidth),
|
_aboutGroup(st::normalFont, lng_create_group_about(lt_count, Global::MegagroupSizeMax()), _defaultOptions, _aboutGroupWidth),
|
||||||
_aboutChannel(st::normalFont, lang(lng_create_channel_about), _defaultOptions, _aboutGroupWidth),
|
_aboutChannel(st::normalFont, lang(lng_create_channel_about), _defaultOptions, _aboutGroupWidth),
|
||||||
_next(this, lang(lng_create_group_next), st::defaultBoxButton),
|
_next(this, lang(lng_create_group_next), st::defaultBoxButton),
|
||||||
_cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
_cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||||
|
@ -499,8 +496,8 @@ void GroupInfoBox::onNext() {
|
||||||
Ui::showLayer(new ContactsBox(title, _photoBig), KeepOtherLayers);
|
Ui::showLayer(new ContactsBox(title, _photoBig), KeepOtherLayers);
|
||||||
} else {
|
} else {
|
||||||
bool mega = false;
|
bool mega = false;
|
||||||
int32 flags = mega ? MTPchannels_CreateChannel::flag_megagroup : MTPchannels_CreateChannel::flag_broadcast;
|
MTPchannels_CreateChannel::Flags flags = mega ? MTPchannels_CreateChannel::Flag::f_megagroup : MTPchannels_CreateChannel::Flag::f_broadcast;
|
||||||
_creationRequestId = MTP::send(MTPchannels_CreateChannel(MTP_int(flags), MTP_string(title), MTP_string(description)), rpcDone(&GroupInfoBox::creationDone), rpcFail(&GroupInfoBox::creationFail));
|
_creationRequestId = MTP::send(MTPchannels_CreateChannel(MTP_flags(flags), MTP_string(title), MTP_string(description)), rpcDone(&GroupInfoBox::creationDone), rpcFail(&GroupInfoBox::creationFail));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,6 +537,9 @@ bool GroupInfoBox::creationFail(const RPCError &error) {
|
||||||
_title.setFocus();
|
_title.setFocus();
|
||||||
_title.showError();
|
_title.showError();
|
||||||
return true;
|
return true;
|
||||||
|
} else if (error.type() == qstr("USER_RESTRICTED")) {
|
||||||
|
Ui::showLayer(new InformBox(lang(lng_cant_do_this)));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -605,12 +605,12 @@ void GroupInfoBox::onPhotoReady(const QImage &img) {
|
||||||
SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : AbstractBox()
|
SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : AbstractBox()
|
||||||
, _channel(channel)
|
, _channel(channel)
|
||||||
, _existing(existing)
|
, _existing(existing)
|
||||||
, _public(this, qsl("channel_privacy"), 0, lang(lng_create_public_channel_title), true)
|
, _public(this, qsl("channel_privacy"), 0, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), true)
|
||||||
, _private(this, qsl("channel_privacy"), 1, lang(lng_create_private_channel_title))
|
, _private(this, qsl("channel_privacy"), 1, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title))
|
||||||
, _comments(this, lang(lng_create_channel_comments), false)
|
, _comments(this, lang(lng_create_channel_comments), false)
|
||||||
, _aboutPublicWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x())
|
, _aboutPublicWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x())
|
||||||
, _aboutPublic(st::normalFont, lang(lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth)
|
, _aboutPublic(st::normalFont, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth)
|
||||||
, _aboutPrivate(st::normalFont, lang(lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth)
|
, _aboutPrivate(st::normalFont, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth)
|
||||||
, _aboutComments(st::normalFont, lang(lng_create_channel_comments_about), _defaultOptions, _aboutPublicWidth)
|
, _aboutComments(st::normalFont, lang(lng_create_channel_comments_about), _defaultOptions, _aboutPublicWidth)
|
||||||
, _link(this, st::defaultInputField, QString(), channel->username, true)
|
, _link(this, st::defaultInputField, QString(), channel->username, true)
|
||||||
, _linkOver(false)
|
, _linkOver(false)
|
||||||
|
@ -626,7 +626,7 @@ SetupChannelBox::SetupChannelBox(ChannelData *channel, bool existing) : Abstract
|
||||||
_checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string("preston")), RPCDoneHandlerPtr(), rpcFail(&SetupChannelBox::onFirstCheckFail));
|
_checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string("preston")), RPCDoneHandlerPtr(), rpcFail(&SetupChannelBox::onFirstCheckFail));
|
||||||
|
|
||||||
_aboutPublicHeight = _aboutPublic.countHeight(_aboutPublicWidth);
|
_aboutPublicHeight = _aboutPublic.countHeight(_aboutPublicWidth);
|
||||||
setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top() + _link.height() + st::newGroupLinkPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
|
updateMaxHeight();
|
||||||
|
|
||||||
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||||
connect(&_skip, SIGNAL(clicked()), this, SLOT(onClose()));
|
connect(&_skip, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
@ -669,6 +669,14 @@ void SetupChannelBox::showDone() {
|
||||||
_link.setFocus();
|
_link.setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupChannelBox::updateMaxHeight() {
|
||||||
|
if (!_channel->isMegagroup() || _public.checked()) {
|
||||||
|
setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::newGroupLinkPadding.top() + _link.height() + st::newGroupLinkPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
|
||||||
|
} else {
|
||||||
|
setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _public.height() + _aboutPublicHeight + st::newGroupSkip + _private.height() + _aboutPrivate.countHeight(_aboutPublicWidth)/* + st::newGroupSkip + _comments.height() + _aboutComments.countHeight(_aboutPublicWidth)*/ + st::newGroupSkip + st::newGroupPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SetupChannelBox::keyPressEvent(QKeyEvent *e) {
|
void SetupChannelBox::keyPressEvent(QKeyEvent *e) {
|
||||||
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
||||||
if (_link.hasFocus()) {
|
if (_link.hasFocus()) {
|
||||||
|
@ -699,22 +707,26 @@ void SetupChannelBox::paintEvent(QPaintEvent *e) {
|
||||||
//QRect aboutComments(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _comments.y() + _comments.height(), _aboutPublicWidth, _aboutPublicHeight);
|
//QRect aboutComments(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _comments.y() + _comments.height(), _aboutPublicWidth, _aboutPublicHeight);
|
||||||
//_aboutComments.drawLeft(p, aboutComments.x(), aboutComments.y(), aboutComments.width(), width());
|
//_aboutComments.drawLeft(p, aboutComments.x(), aboutComments.y(), aboutComments.width(), width());
|
||||||
|
|
||||||
p.setPen(st::black);
|
if (!_channel->isMegagroup() || !_link.isHidden()) {
|
||||||
p.setFont(st::newGroupLinkFont);
|
p.setPen(st::black);
|
||||||
p.drawTextLeft(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultInputField.textMargins.left(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop, width(), lang(_link.isHidden() ? lng_create_group_invite_link : lng_create_group_link));
|
p.setFont(st::newGroupLinkFont);
|
||||||
|
p.drawTextLeft(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultInputField.textMargins.left(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop, width(), lang(_link.isHidden() ? lng_create_group_invite_link : lng_create_group_link));
|
||||||
|
}
|
||||||
|
|
||||||
if (_link.isHidden()) {
|
if (_link.isHidden()) {
|
||||||
QTextOption option(style::al_left);
|
if (!_channel->isMegagroup()) {
|
||||||
option.setWrapMode(QTextOption::WrapAnywhere);
|
QTextOption option(style::al_left);
|
||||||
p.setFont(_linkOver ? st::boxTextFont->underline() : st::boxTextFont);
|
option.setWrapMode(QTextOption::WrapAnywhere);
|
||||||
p.setPen(st::btnDefLink.color);
|
p.setFont(_linkOver ? st::boxTextFont->underline() : st::boxTextFont);
|
||||||
p.drawText(_invitationLink, _channel->invitationUrl, option);
|
p.setPen(st::btnDefLink.color);
|
||||||
if (!_goodTextLink.isEmpty() && a_goodOpacity.current() > 0) {
|
p.drawText(_invitationLink, _channel->invitationUrl, option);
|
||||||
p.setOpacity(a_goodOpacity.current());
|
if (!_goodTextLink.isEmpty() && a_goodOpacity.current() > 0) {
|
||||||
p.setPen(st::setGoodColor);
|
p.setOpacity(a_goodOpacity.current());
|
||||||
p.setFont(st::boxTextFont);
|
p.setPen(st::setGoodColor);
|
||||||
p.drawTextRight(st::boxPadding.right(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, width(), _goodTextLink);
|
p.setFont(st::boxTextFont);
|
||||||
p.setOpacity(1);
|
p.drawTextRight(st::boxPadding.right(), _link.y() - st::newGroupLinkPadding.top() + st::newGroupLinkTop + st::newGroupLinkFont->ascent - st::boxTextFont->ascent, width(), _goodTextLink);
|
||||||
|
p.setOpacity(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_errorText.isEmpty()) {
|
if (!_errorText.isEmpty()) {
|
||||||
|
@ -750,7 +762,7 @@ void SetupChannelBox::mouseMoveEvent(QMouseEvent *e) {
|
||||||
void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
|
void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
|
||||||
mouseMoveEvent(e);
|
mouseMoveEvent(e);
|
||||||
if (_linkOver) {
|
if (_linkOver) {
|
||||||
App::app()->clipboard()->setText(_channel->invitationUrl);
|
Application::clipboard()->setText(_channel->invitationUrl);
|
||||||
_goodTextLink = lang(lng_create_channel_link_copied);
|
_goodTextLink = lang(lng_create_channel_link_copied);
|
||||||
a_goodOpacity = anim::fvalue(1, 0);
|
a_goodOpacity = anim::fvalue(1, 0);
|
||||||
_a_goodFade.start();
|
_a_goodFade.start();
|
||||||
|
@ -827,7 +839,7 @@ void SetupChannelBox::onChange() {
|
||||||
}
|
}
|
||||||
_checkTimer.stop();
|
_checkTimer.stop();
|
||||||
} else {
|
} else {
|
||||||
int32 i, len = name.size();
|
int32 len = name.size();
|
||||||
for (int32 i = 0; i < len; ++i) {
|
for (int32 i = 0; i < len; ++i) {
|
||||||
QChar ch = name.at(i);
|
QChar ch = name.at(i);
|
||||||
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_') {
|
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_') {
|
||||||
|
@ -879,6 +891,9 @@ void SetupChannelBox::onPrivacyChange() {
|
||||||
_link.hide();
|
_link.hide();
|
||||||
setFocus();
|
setFocus();
|
||||||
}
|
}
|
||||||
|
if (_channel->isMegagroup()) {
|
||||||
|
updateMaxHeight();
|
||||||
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,7 +944,10 @@ bool SetupChannelBox::onCheckFail(const RPCError &error) {
|
||||||
|
|
||||||
_checkRequestId = 0;
|
_checkRequestId = 0;
|
||||||
QString err(error.type());
|
QString err(error.type());
|
||||||
if (err == "CHANNELS_ADMIN_PUBLIC_TOO_MUCH") {
|
if (err == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
} else if (err == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
|
||||||
if (_existing) {
|
if (_existing) {
|
||||||
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -938,11 +956,11 @@ bool SetupChannelBox::onCheckFail(const RPCError &error) {
|
||||||
onPrivacyChange();
|
onPrivacyChange();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (err == "USERNAME_INVALID") {
|
} else if (err == qstr("USERNAME_INVALID")) {
|
||||||
_errorText = lang(lng_create_channel_link_invalid);
|
_errorText = lang(lng_create_channel_link_invalid);
|
||||||
update();
|
update();
|
||||||
return true;
|
return true;
|
||||||
} else if (err == "USERNAME_OCCUPIED" && _checkUsername != _channel->username) {
|
} else if (err == qstr("USERNAME_OCCUPIED") && _checkUsername != _channel->username) {
|
||||||
_errorText = lang(lng_create_channel_link_occupied);
|
_errorText = lang(lng_create_channel_link_occupied);
|
||||||
update();
|
update();
|
||||||
return true;
|
return true;
|
||||||
|
@ -957,7 +975,10 @@ bool SetupChannelBox::onFirstCheckFail(const RPCError &error) {
|
||||||
|
|
||||||
_checkRequestId = 0;
|
_checkRequestId = 0;
|
||||||
QString err(error.type());
|
QString err(error.type());
|
||||||
if (err == "CHANNELS_ADMIN_PUBLIC_TOO_MUCH") {
|
if (err == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
} else if (err == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
|
||||||
if (_existing) {
|
if (_existing) {
|
||||||
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
Ui::showLayer(new InformBox(lang(lng_channels_too_much_public_existing)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1094,7 +1115,8 @@ void EditNameTitleBox::onSave() {
|
||||||
}
|
}
|
||||||
_sentName = first;
|
_sentName = first;
|
||||||
if (_peer == App::self()) {
|
if (_peer == App::self()) {
|
||||||
_requestId = MTP::send(MTPaccount_UpdateProfile(MTP_string(first), MTP_string(last)), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail));
|
MTPaccount_UpdateProfile::Flags flags = MTPaccount_UpdateProfile::Flag::f_first_name | MTPaccount_UpdateProfile::Flag::f_last_name;
|
||||||
|
_requestId = MTP::send(MTPaccount_UpdateProfile(MTP_flags(flags), MTP_string(first), MTP_string(last), MTPstring()), rpcDone(&EditNameTitleBox::onSaveSelfDone), rpcFail(&EditNameTitleBox::onSaveSelfFail));
|
||||||
} else if (_peer->isChat()) {
|
} else if (_peer->isChat()) {
|
||||||
_requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail));
|
_requestId = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(first)), rpcDone(&EditNameTitleBox::onSaveChatDone), rpcFail(&EditNameTitleBox::onSaveChatFail));
|
||||||
}
|
}
|
||||||
|
@ -1150,14 +1172,17 @@ void EditNameTitleBox::onSaveChatDone(const MTPUpdates &updates) {
|
||||||
emit closed();
|
emit closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
EditChannelBox::EditChannelBox(ChannelData *channel) :
|
EditChannelBox::EditChannelBox(ChannelData *channel) : AbstractBox()
|
||||||
_channel(channel),
|
, _channel(channel)
|
||||||
_save(this, lang(lng_settings_save), st::defaultBoxButton),
|
, _save(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||||
_cancel(this, lang(lng_cancel), st::cancelBoxButton),
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||||
_title(this, st::defaultInputField, lang(lng_dlg_new_channel_name), _channel->name),
|
, _title(this, st::defaultInputField, lang(lng_dlg_new_channel_name), _channel->name)
|
||||||
_description(this, st::newGroupDescription, lang(lng_create_group_description), _channel->about),
|
, _description(this, st::newGroupDescription, lang(lng_create_group_description), _channel->about)
|
||||||
_publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), st::defaultBoxLinkButton),
|
, _sign(this, lang(lng_edit_sign_messages), channel->addsSignature())
|
||||||
_saveTitleRequestId(0), _saveDescriptionRequestId(0) {
|
, _publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), st::defaultBoxLinkButton)
|
||||||
|
, _saveTitleRequestId(0)
|
||||||
|
, _saveDescriptionRequestId(0)
|
||||||
|
, _saveSignRequestId(0) {
|
||||||
connect(App::main(), SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(peerUpdated(PeerData*)));
|
connect(App::main(), SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(peerUpdated(PeerData*)));
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
@ -1183,6 +1208,7 @@ _saveTitleRequestId(0), _saveDescriptionRequestId(0) {
|
||||||
void EditChannelBox::hideAll() {
|
void EditChannelBox::hideAll() {
|
||||||
_title.hide();
|
_title.hide();
|
||||||
_description.hide();
|
_description.hide();
|
||||||
|
_sign.hide();
|
||||||
_save.hide();
|
_save.hide();
|
||||||
_cancel.hide();
|
_cancel.hide();
|
||||||
_publicLink.hide();
|
_publicLink.hide();
|
||||||
|
@ -1193,10 +1219,15 @@ void EditChannelBox::showAll() {
|
||||||
_description.show();
|
_description.show();
|
||||||
_save.show();
|
_save.show();
|
||||||
_cancel.show();
|
_cancel.show();
|
||||||
if (_channel->isMegagroup()) {
|
if (_channel->canEditUsername()) {
|
||||||
_publicLink.hide();
|
|
||||||
} else {
|
|
||||||
_publicLink.show();
|
_publicLink.show();
|
||||||
|
} else {
|
||||||
|
_publicLink.hide();
|
||||||
|
}
|
||||||
|
if (_channel->isMegagroup()) {
|
||||||
|
_sign.hide();
|
||||||
|
} else {
|
||||||
|
_sign.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1224,6 +1255,7 @@ void EditChannelBox::paintEvent(QPaintEvent *e) {
|
||||||
void EditChannelBox::peerUpdated(PeerData *peer) {
|
void EditChannelBox::peerUpdated(PeerData *peer) {
|
||||||
if (peer == _channel) {
|
if (peer == _channel) {
|
||||||
_publicLink.setText(lang(_channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link));
|
_publicLink.setText(lang(_channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link));
|
||||||
|
_sign.setChecked(_channel->addsSignature());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1235,7 +1267,12 @@ void EditChannelBox::onDescriptionResized() {
|
||||||
void EditChannelBox::updateMaxHeight() {
|
void EditChannelBox::updateMaxHeight() {
|
||||||
int32 h = st::boxTitleHeight + st::newGroupInfoPadding.top() + _title.height();
|
int32 h = st::boxTitleHeight + st::newGroupInfoPadding.top() + _title.height();
|
||||||
h += st::newGroupDescriptionPadding.top() + _description.height() + st::newGroupDescriptionPadding.bottom();
|
h += st::newGroupDescriptionPadding.top() + _description.height() + st::newGroupDescriptionPadding.bottom();
|
||||||
h += st::newGroupPublicLinkPadding.top() + _publicLink.height() + st::newGroupPublicLinkPadding.bottom();
|
if (!_channel->isMegagroup()) {
|
||||||
|
h += st::newGroupPublicLinkPadding.top() + _sign.height() + st::newGroupPublicLinkPadding.bottom();
|
||||||
|
}
|
||||||
|
if (_channel->canEditUsername()) {
|
||||||
|
h += st::newGroupPublicLinkPadding.top() + _publicLink.height() + st::newGroupPublicLinkPadding.bottom();
|
||||||
|
}
|
||||||
h += st::boxPadding.bottom() + st::newGroupInfoPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom();
|
h += st::boxPadding.bottom() + st::newGroupInfoPadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom();
|
||||||
setMaxHeight(h);
|
setMaxHeight(h);
|
||||||
}
|
}
|
||||||
|
@ -1246,14 +1283,20 @@ void EditChannelBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
_description.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _title.y() + _title.height() + st::newGroupDescriptionPadding.top());
|
_description.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _title.y() + _title.height() + st::newGroupDescriptionPadding.top());
|
||||||
|
|
||||||
_publicLink.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
_sign.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||||
|
|
||||||
|
if (_channel->isMegagroup()) {
|
||||||
|
_publicLink.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||||
|
} else {
|
||||||
|
_publicLink.moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _sign.y() + _sign.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||||
|
}
|
||||||
|
|
||||||
_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
|
_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
|
||||||
_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());
|
_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditChannelBox::onSave() {
|
void EditChannelBox::onSave() {
|
||||||
if (_saveTitleRequestId || _saveDescriptionRequestId) return;
|
if (_saveTitleRequestId || _saveDescriptionRequestId || _saveSignRequestId) return;
|
||||||
|
|
||||||
QString title = prepareText(_title.getLastText()), description = prepareText(_description.getLastText(), true);
|
QString title = prepareText(_title.getLastText()), description = prepareText(_description.getLastText(), true);
|
||||||
if (title.isEmpty()) {
|
if (title.isEmpty()) {
|
||||||
|
@ -1263,7 +1306,11 @@ void EditChannelBox::onSave() {
|
||||||
}
|
}
|
||||||
_sentTitle = title;
|
_sentTitle = title;
|
||||||
_sentDescription = description;
|
_sentDescription = description;
|
||||||
_saveTitleRequestId = MTP::send(MTPchannels_EditTitle(_channel->inputChannel, MTP_string(_sentTitle)), rpcDone(&EditChannelBox::onSaveTitleDone), rpcFail(&EditChannelBox::onSaveFail));
|
if (_sentTitle == _channel->name) {
|
||||||
|
saveDescription();
|
||||||
|
} else {
|
||||||
|
_saveTitleRequestId = MTP::send(MTPchannels_EditTitle(_channel->inputChannel, MTP_string(_sentTitle)), rpcDone(&EditChannelBox::onSaveTitleDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditChannelBox::onPublicLink() {
|
void EditChannelBox::onPublicLink() {
|
||||||
|
@ -1271,7 +1318,19 @@ void EditChannelBox::onPublicLink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditChannelBox::saveDescription() {
|
void EditChannelBox::saveDescription() {
|
||||||
_saveDescriptionRequestId = MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail));
|
if (_sentDescription == _channel->about) {
|
||||||
|
saveSign();
|
||||||
|
} else {
|
||||||
|
_saveDescriptionRequestId = MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditChannelBox::saveSign() {
|
||||||
|
if (_channel->isMegagroup() || _channel->addsSignature() == _sign.checked()) {
|
||||||
|
onClose();
|
||||||
|
} else {
|
||||||
|
_saveSignRequestId = MTP::send(MTPchannels_ToggleSignatures(_channel->inputChannel, MTP_bool(_sign.checked())), rpcDone(&EditChannelBox::onSaveSignDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) {
|
bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) {
|
||||||
|
@ -1295,24 +1354,46 @@ bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) {
|
||||||
_saveDescriptionRequestId = 0;
|
_saveDescriptionRequestId = 0;
|
||||||
if (err == qstr("CHAT_ABOUT_NOT_MODIFIED")) {
|
if (err == qstr("CHAT_ABOUT_NOT_MODIFIED")) {
|
||||||
_channel->about = _sentDescription;
|
_channel->about = _sentDescription;
|
||||||
if (App::api()) emit App::api()->fullPeerUpdated(_channel);
|
if (App::api()) {
|
||||||
onClose();
|
emit App::api()->fullPeerUpdated(_channel);
|
||||||
|
}
|
||||||
|
saveSign();
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
_description.setFocus();
|
_description.setFocus();
|
||||||
}
|
}
|
||||||
|
} else if (req == _saveSignRequestId) {
|
||||||
|
_saveSignRequestId = 0;
|
||||||
|
if (err == qstr("CHAT_NOT_MODIFIED")) {
|
||||||
|
onClose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditChannelBox::onSaveTitleDone(const MTPUpdates &updates) {
|
void EditChannelBox::onSaveTitleDone(const MTPUpdates &updates) {
|
||||||
_saveTitleRequestId = 0;
|
_saveTitleRequestId = 0;
|
||||||
App::main()->sentUpdatesReceived(updates);
|
if (App::main()) {
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
}
|
||||||
saveDescription();
|
saveDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditChannelBox::onSaveDescriptionDone(const MTPBool &result) {
|
void EditChannelBox::onSaveDescriptionDone(const MTPBool &result) {
|
||||||
_saveDescriptionRequestId = 0;
|
_saveDescriptionRequestId = 0;
|
||||||
_channel->about = _sentDescription;
|
_channel->about = _sentDescription;
|
||||||
if (App::api()) emit App::api()->fullPeerUpdated(_channel);
|
if (App::api()) {
|
||||||
|
emit App::api()->fullPeerUpdated(_channel);
|
||||||
|
}
|
||||||
|
saveSign();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditChannelBox::onSaveSignDone(const MTPUpdates &updates) {
|
||||||
|
_saveSignRequestId = 0;
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
}
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -211,6 +211,8 @@ private:
|
||||||
bool onCheckFail(const RPCError &error);
|
bool onCheckFail(const RPCError &error);
|
||||||
bool onFirstCheckFail(const RPCError &error);
|
bool onFirstCheckFail(const RPCError &error);
|
||||||
|
|
||||||
|
void updateMaxHeight();
|
||||||
|
|
||||||
ChannelData *_channel;
|
ChannelData *_channel;
|
||||||
bool _existing;
|
bool _existing;
|
||||||
|
|
||||||
|
@ -315,18 +317,21 @@ private:
|
||||||
|
|
||||||
void onSaveTitleDone(const MTPUpdates &updates);
|
void onSaveTitleDone(const MTPUpdates &updates);
|
||||||
void onSaveDescriptionDone(const MTPBool &result);
|
void onSaveDescriptionDone(const MTPBool &result);
|
||||||
|
void onSaveSignDone(const MTPUpdates &updates);
|
||||||
bool onSaveFail(const RPCError &e, mtpRequestId req);
|
bool onSaveFail(const RPCError &e, mtpRequestId req);
|
||||||
|
|
||||||
void saveDescription();
|
void saveDescription();
|
||||||
|
void saveSign();
|
||||||
|
|
||||||
ChannelData *_channel;
|
ChannelData *_channel;
|
||||||
|
|
||||||
BoxButton _save, _cancel;
|
BoxButton _save, _cancel;
|
||||||
InputField _title;
|
InputField _title;
|
||||||
InputArea _description;
|
InputArea _description;
|
||||||
|
Checkbox _sign;
|
||||||
|
|
||||||
LinkButton _publicLink;
|
LinkButton _publicLink;
|
||||||
|
|
||||||
mtpRequestId _saveTitleRequestId, _saveDescriptionRequestId;
|
mtpRequestId _saveTitleRequestId, _saveDescriptionRequestId, _saveSignRequestId;
|
||||||
QString _sentTitle, _sentDescription;
|
QString _sentTitle, _sentDescription;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -34,19 +34,19 @@ TextParseOptions _confirmBoxTextOptions = {
|
||||||
Qt::LayoutDirectionAuto, // dir
|
Qt::LayoutDirectionAuto, // dir
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, const QString &cancelText, const style::BoxButton &cancelStyle) : AbstractBox(st::boxWidth),
|
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, const QString &cancelText, const style::BoxButton &cancelStyle) : AbstractBox(st::boxWidth)
|
||||||
_informative(false),
|
, _informative(false)
|
||||||
_text(100),
|
, _text(100)
|
||||||
_confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle),
|
, _confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle)
|
||||||
_cancel(this, cancelText.isEmpty() ? lang(lng_cancel) : cancelText, cancelStyle) {
|
, _cancel(this, cancelText.isEmpty() ? lang(lng_cancel) : cancelText, cancelStyle) {
|
||||||
init(text);
|
init(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, bool informative) : AbstractBox(st::boxWidth),
|
ConfirmBox::ConfirmBox(const QString &text, const QString &doneText, const style::BoxButton &doneStyle, bool informative) : AbstractBox(st::boxWidth)
|
||||||
_informative(true),
|
, _informative(true)
|
||||||
_text(100),
|
, _text(100)
|
||||||
_confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle),
|
, _confirm(this, doneText.isEmpty() ? lang(lng_box_ok) : doneText, doneStyle)
|
||||||
_cancel(this, QString(), st::cancelBoxButton) {
|
, _cancel(this, QString(), st::cancelBoxButton) {
|
||||||
init(text);
|
init(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,33 +83,30 @@ void ConfirmBox::mouseMoveEvent(QMouseEvent *e) {
|
||||||
void ConfirmBox::mousePressEvent(QMouseEvent *e) {
|
void ConfirmBox::mousePressEvent(QMouseEvent *e) {
|
||||||
_lastMousePos = e->globalPos();
|
_lastMousePos = e->globalPos();
|
||||||
updateHover();
|
updateHover();
|
||||||
if (textlnkOver()) {
|
ClickHandler::pressed();
|
||||||
textlnkDown(textlnkOver());
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
return LayeredWidget::mousePressEvent(e);
|
return LayeredWidget::mousePressEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmBox::mouseReleaseEvent(QMouseEvent *e) {
|
void ConfirmBox::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
_lastMousePos = e->globalPos();
|
_lastMousePos = e->globalPos();
|
||||||
updateHover();
|
updateHover();
|
||||||
if (textlnkOver() && textlnkOver() == textlnkDown()) {
|
if (ClickHandlerPtr activated = ClickHandler::unpressed()) {
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
textlnkOver()->onClick(e->button());
|
App::activateClickHandler(activated, e->button());
|
||||||
}
|
}
|
||||||
textlnkDown(TextLinkPtr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmBox::leaveEvent(QEvent *e) {
|
void ConfirmBox::leaveEvent(QEvent *e) {
|
||||||
if (_myLink) {
|
ClickHandler::clearActive(this);
|
||||||
if (textlnkOver() == _myLink) {
|
}
|
||||||
textlnkOver(TextLinkPtr());
|
|
||||||
update();
|
void ConfirmBox::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||||
}
|
setCursor(active ? style::cur_pointer : style::cur_default);
|
||||||
_myLink = TextLinkPtr();
|
update();
|
||||||
setCursor(style::cur_default);
|
}
|
||||||
update();
|
|
||||||
}
|
void ConfirmBox::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) {
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmBox::updateLink() {
|
void ConfirmBox::updateLink() {
|
||||||
|
@ -119,17 +116,12 @@ void ConfirmBox::updateLink() {
|
||||||
|
|
||||||
void ConfirmBox::updateHover() {
|
void ConfirmBox::updateHover() {
|
||||||
QPoint m(mapFromGlobal(_lastMousePos));
|
QPoint m(mapFromGlobal(_lastMousePos));
|
||||||
bool wasMy = (_myLink == textlnkOver());
|
|
||||||
textstyleSet(&st::boxTextStyle);
|
textstyleSet(&st::boxTextStyle);
|
||||||
_myLink = _text.linkLeft(m.x() - st::boxPadding.left(), m.y() - st::boxPadding.top(), _textWidth, width(), (_text.maxWidth() < width()) ? style::al_center : style::al_left);
|
ClickHandlerPtr handler = _text.linkLeft(m.x() - st::boxPadding.left(), m.y() - st::boxPadding.top(), _textWidth, width(), style::al_left);
|
||||||
textstyleRestore();
|
textstyleRestore();
|
||||||
if (_myLink != textlnkOver()) {
|
|
||||||
if (wasMy || _myLink || rect().contains(m)) {
|
ClickHandler::setActive(handler, this);
|
||||||
textlnkOver(_myLink);
|
|
||||||
}
|
|
||||||
setCursor(_myLink ? style::cur_pointer : style::cur_default);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmBox::closePressed() {
|
void ConfirmBox::closePressed() {
|
||||||
|
@ -174,22 +166,29 @@ void ConfirmBox::resizeEvent(QResizeEvent *e) {
|
||||||
_cancel.moveToRight(st::boxButtonPadding.right() + _confirm.width() + st::boxButtonPadding.left(), _confirm.y());
|
_cancel.moveToRight(st::boxButtonPadding.right() + _confirm.width() + st::boxButtonPadding.left(), _confirm.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmLinkBox::ConfirmLinkBox(const QString &url) : ConfirmBox(lang(lng_open_this_link) + qsl("\n\n") + url, lang(lng_open_link)), _url(url) {
|
SharePhoneConfirmBox::SharePhoneConfirmBox(PeerData *recipient)
|
||||||
|
: ConfirmBox(lang(lng_bot_share_phone), lang(lng_bot_share_phone_confirm))
|
||||||
|
, _recipient(recipient) {
|
||||||
|
connect(this, SIGNAL(confirmed()), this, SLOT(onConfirm()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharePhoneConfirmBox::onConfirm() {
|
||||||
|
emit confirmed(_recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmLinkBox::ConfirmLinkBox(const QString &url) : ConfirmBox(lang(lng_open_this_link) + qsl("\n\n") + url, lang(lng_open_link))
|
||||||
|
, _url(url) {
|
||||||
connect(this, SIGNAL(confirmed()), this, SLOT(onOpenLink()));
|
connect(this, SIGNAL(confirmed()), this, SLOT(onOpenLink()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmLinkBox::onOpenLink() {
|
void ConfirmLinkBox::onOpenLink() {
|
||||||
if (reMailStart().match(_url).hasMatch()) {
|
|
||||||
EmailLink(_url).onClick(Qt::LeftButton);
|
|
||||||
} else {
|
|
||||||
TextLink(_url).onClick(Qt::LeftButton);
|
|
||||||
}
|
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
|
UrlClickHandler::doOpen(_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaxInviteBox::MaxInviteBox(const QString &link) : AbstractBox(st::boxWidth)
|
MaxInviteBox::MaxInviteBox(const QString &link) : AbstractBox(st::boxWidth)
|
||||||
, _close(this, lang(lng_box_ok), st::defaultBoxButton)
|
, _close(this, lang(lng_box_ok), st::defaultBoxButton)
|
||||||
, _text(st::boxTextFont, lng_participant_invite_sorry(lt_count, cMaxGroupCount()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right())
|
, _text(st::boxTextFont, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right())
|
||||||
, _link(link)
|
, _link(link)
|
||||||
, _linkOver(false)
|
, _linkOver(false)
|
||||||
, a_goodOpacity(0, 0)
|
, a_goodOpacity(0, 0)
|
||||||
|
@ -212,7 +211,7 @@ void MaxInviteBox::mouseMoveEvent(QMouseEvent *e) {
|
||||||
void MaxInviteBox::mousePressEvent(QMouseEvent *e) {
|
void MaxInviteBox::mousePressEvent(QMouseEvent *e) {
|
||||||
mouseMoveEvent(e);
|
mouseMoveEvent(e);
|
||||||
if (_linkOver) {
|
if (_linkOver) {
|
||||||
App::app()->clipboard()->setText(_link);
|
Application::clipboard()->setText(_link);
|
||||||
_goodTextLink = lang(lng_create_channel_link_copied);
|
_goodTextLink = lang(lng_create_channel_link_copied);
|
||||||
a_goodOpacity = anim::fvalue(1, 0);
|
a_goodOpacity = anim::fvalue(1, 0);
|
||||||
_a_good.start();
|
_a_good.start();
|
||||||
|
@ -279,3 +278,228 @@ void MaxInviteBox::resizeEvent(QResizeEvent *e) {
|
||||||
_close.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _close.height());
|
_close.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _close.height());
|
||||||
_invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height);
|
_invitationLink = myrtlrect(st::boxPadding.left(), st::boxPadding.top() + _textHeight + st::boxTextFont->height, width() - st::boxPadding.left() - st::boxPadding.right(), 2 * st::boxTextFont->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConvertToSupergroupBox::ConvertToSupergroupBox(ChatData *chat) : AbstractBox(st::boxWideWidth)
|
||||||
|
, _chat(chat)
|
||||||
|
, _text(100)
|
||||||
|
, _note(100)
|
||||||
|
, _convert(this, lang(lng_profile_convert_confirm), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||||
|
QStringList text;
|
||||||
|
text.push_back(lang(lng_profile_convert_feature1));
|
||||||
|
text.push_back(lang(lng_profile_convert_feature2));
|
||||||
|
text.push_back(lang(lng_profile_convert_feature3));
|
||||||
|
text.push_back(lang(lng_profile_convert_feature4));
|
||||||
|
|
||||||
|
textstyleSet(&st::boxTextStyle);
|
||||||
|
_text.setText(st::boxTextFont, text.join('\n'), _confirmBoxTextOptions);
|
||||||
|
_note.setText(st::boxTextFont, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
|
||||||
|
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
||||||
|
_textHeight = _text.countHeight(_textWidth);
|
||||||
|
setMaxHeight(st::boxTitleHeight + _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth) + st::boxButtonPadding.top() + _convert.height() + st::boxButtonPadding.bottom());
|
||||||
|
textstyleRestore();
|
||||||
|
|
||||||
|
connect(&_convert, SIGNAL(clicked()), this, SLOT(onConvert()));
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::onConvert() {
|
||||||
|
MTP::send(MTPmessages_MigrateChat(_chat->inputChat), rpcDone(&ConvertToSupergroupBox::convertDone), rpcFail(&ConvertToSupergroupBox::convertFail));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::convertDone(const MTPUpdates &updates) {
|
||||||
|
Ui::hideLayer();
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
const QVector<MTPChat> *v = 0;
|
||||||
|
switch (updates.type()) {
|
||||||
|
case mtpc_updates: v = &updates.c_updates().vchats.c_vector().v; break;
|
||||||
|
case mtpc_updatesCombined: v = &updates.c_updatesCombined().vchats.c_vector().v; break;
|
||||||
|
default: LOG(("API Error: unexpected update cons %1 (ConvertToSupergroupBox::convertDone)").arg(updates.type())); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PeerData *peer = 0;
|
||||||
|
if (v && !v->isEmpty()) {
|
||||||
|
for (int32 i = 0, l = v->size(); i < l; ++i) {
|
||||||
|
if (v->at(i).type() == mtpc_channel) {
|
||||||
|
peer = App::channel(v->at(i).c_channel().vid.v);
|
||||||
|
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
||||||
|
QTimer::singleShot(ReloadChannelMembersTimeout, App::api(), SLOT(delayedRequestParticipantsCount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!peer) {
|
||||||
|
LOG(("API Error: channel not found in updates (ProfileInner::migrateDone)"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConvertToSupergroupBox::convertFail(const RPCError &error) {
|
||||||
|
if (mtpIsFlood(error)) return false;
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::hideAll() {
|
||||||
|
_convert.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::showAll() {
|
||||||
|
_convert.show();
|
||||||
|
_cancel.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::keyPressEvent(QKeyEvent *e) {
|
||||||
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
||||||
|
onConvert();
|
||||||
|
} else {
|
||||||
|
AbstractBox::keyPressEvent(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
if (paint(p)) return;
|
||||||
|
|
||||||
|
paintTitle(p, lang(lng_profile_convert_title));
|
||||||
|
|
||||||
|
// draw box title / text
|
||||||
|
p.setPen(st::black);
|
||||||
|
textstyleSet(&st::boxTextStyle);
|
||||||
|
_text.drawLeft(p, st::boxPadding.left(), st::boxTitleHeight, _textWidth, width());
|
||||||
|
_note.drawLeft(p, st::boxPadding.left(), st::boxTitleHeight + _textHeight + st::boxPadding.bottom(), _textWidth, width());
|
||||||
|
textstyleRestore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertToSupergroupBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
_convert.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _convert.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _convert.width() + st::boxButtonPadding.left(), _convert.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
PinMessageBox::PinMessageBox(ChannelData *channel, MsgId msgId) : AbstractBox(st::boxWidth)
|
||||||
|
, _channel(channel)
|
||||||
|
, _msgId(msgId)
|
||||||
|
, _text(this, lang(lng_pinned_pin_sure), st::boxLabel)
|
||||||
|
, _notify(this, lang(lng_pinned_notify), true)
|
||||||
|
, _pin(this, lang(lng_pinned_pin), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||||
|
, _requestId(0) {
|
||||||
|
_text.resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
|
||||||
|
setMaxHeight(st::boxPadding.top() + _text.height() + st::boxMediumSkip + _notify.height() + st::boxPadding.bottom() + st::boxButtonPadding.top() + _pin.height() + st::boxButtonPadding.bottom());
|
||||||
|
|
||||||
|
connect(&_pin, SIGNAL(clicked()), this, SLOT(onPin()));
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
_text.moveToLeft(st::boxPadding.left(), st::boxPadding.top());
|
||||||
|
_notify.moveToLeft(st::boxPadding.left(), _text.y() + _text.height() + st::boxMediumSkip);
|
||||||
|
_pin.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _pin.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _pin.width() + st::boxButtonPadding.left(), _pin.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::onPin() {
|
||||||
|
if (_requestId) return;
|
||||||
|
|
||||||
|
MTPchannels_UpdatePinnedMessage::Flags flags = 0;
|
||||||
|
if (_notify.checked()) {
|
||||||
|
flags |= MTPchannels_UpdatePinnedMessage::Flag::f_silent;
|
||||||
|
}
|
||||||
|
_requestId = MTP::send(MTPchannels_UpdatePinnedMessage(MTP_flags(flags), _channel->inputChannel, MTP_int(_msgId)), rpcDone(&PinMessageBox::pinDone), rpcFail(&PinMessageBox::pinFail));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::showAll() {
|
||||||
|
_text.show();
|
||||||
|
_notify.show();
|
||||||
|
_pin.show();
|
||||||
|
_cancel.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::hideAll() {
|
||||||
|
_text.hide();
|
||||||
|
_notify.hide();
|
||||||
|
_pin.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinMessageBox::pinDone(const MTPUpdates &updates) {
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
}
|
||||||
|
Ui::hideLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PinMessageBox::pinFail(const RPCError &error) {
|
||||||
|
if (mtpIsFlood(error)) return false;
|
||||||
|
Ui::hideLayer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RichDeleteMessageBox::RichDeleteMessageBox(ChannelData *channel, UserData *from, MsgId msgId) : AbstractBox(st::boxWidth)
|
||||||
|
, _channel(channel)
|
||||||
|
, _from(from)
|
||||||
|
, _msgId(msgId)
|
||||||
|
, _text(this, lang(lng_selected_delete_sure_this), st::boxLabel)
|
||||||
|
, _banUser(this, lang(lng_ban_user), false)
|
||||||
|
, _reportSpam(this, lang(lng_report_spam), false)
|
||||||
|
, _deleteAll(this, lang(lng_delete_all_from), false)
|
||||||
|
, _delete(this, lang(lng_box_delete), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||||
|
t_assert(_channel != nullptr);
|
||||||
|
|
||||||
|
_text.resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
|
||||||
|
setMaxHeight(st::boxPadding.top() + _text.height() + st::boxMediumSkip + _banUser.height() + st::boxLittleSkip + _reportSpam.height() + st::boxLittleSkip + _deleteAll.height() + st::boxPadding.bottom() + st::boxButtonPadding.top() + _delete.height() + st::boxButtonPadding.bottom());
|
||||||
|
|
||||||
|
connect(&_delete, SIGNAL(clicked()), this, SLOT(onDelete()));
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
_text.moveToLeft(st::boxPadding.left(), st::boxPadding.top());
|
||||||
|
_banUser.moveToLeft(st::boxPadding.left(), _text.y() + _text.height() + st::boxMediumSkip);
|
||||||
|
_reportSpam.moveToLeft(st::boxPadding.left(), _banUser.y() + _banUser.height() + st::boxLittleSkip);
|
||||||
|
_deleteAll.moveToLeft(st::boxPadding.left(), _reportSpam.y() + _reportSpam.height() + st::boxLittleSkip);
|
||||||
|
_delete.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _delete.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _delete.width() + st::boxButtonPadding.left(), _delete.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::onDelete() {
|
||||||
|
if (_banUser.checked()) {
|
||||||
|
MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _from->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
|
||||||
|
}
|
||||||
|
if (_reportSpam.checked()) {
|
||||||
|
MTP::send(MTPchannels_ReportSpam(_channel->inputChannel, _from->inputUser, MTP_vector<MTPint>(1, MTP_int(_msgId))));
|
||||||
|
}
|
||||||
|
if (_deleteAll.checked()) {
|
||||||
|
App::main()->deleteAllFromUser(_channel, _from);
|
||||||
|
}
|
||||||
|
if (HistoryItem *item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId)) {
|
||||||
|
bool wasLast = (item->history()->lastMsg == item);
|
||||||
|
item->destroy();
|
||||||
|
if (_msgId > 0) {
|
||||||
|
App::main()->deleteMessages(_channel, QVector<MTPint>(1, MTP_int(_msgId)));
|
||||||
|
} else if (wasLast) {
|
||||||
|
App::main()->checkPeerHistory(_channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ui::hideLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::showAll() {
|
||||||
|
_text.show();
|
||||||
|
_banUser.show();
|
||||||
|
_reportSpam.show();
|
||||||
|
_deleteAll.show();
|
||||||
|
_delete.show();
|
||||||
|
_cancel.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichDeleteMessageBox::hideAll() {
|
||||||
|
_text.hide();
|
||||||
|
_banUser.hide();
|
||||||
|
_reportSpam.hide();
|
||||||
|
_deleteAll.hide();
|
||||||
|
_delete.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
}
|
||||||
|
|
|
@ -16,14 +16,14 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "abstractbox.h"
|
#include "abstractbox.h"
|
||||||
|
|
||||||
class InformBox;
|
class InformBox;
|
||||||
class ConfirmBox : public AbstractBox {
|
class ConfirmBox : public AbstractBox, public ClickHandlerHost {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -38,6 +38,10 @@ public:
|
||||||
void leaveEvent(QEvent *e);
|
void leaveEvent(QEvent *e);
|
||||||
void updateLink();
|
void updateLink();
|
||||||
|
|
||||||
|
// ClickHandlerHost interface
|
||||||
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active);
|
||||||
|
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onCancel();
|
void onCancel();
|
||||||
|
@ -69,7 +73,6 @@ private:
|
||||||
void updateHover();
|
void updateHover();
|
||||||
|
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
TextLinkPtr _myLink;
|
|
||||||
|
|
||||||
BoxButton _confirm, _cancel;
|
BoxButton _confirm, _cancel;
|
||||||
};
|
};
|
||||||
|
@ -80,6 +83,23 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SharePhoneConfirmBox : public ConfirmBox {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SharePhoneConfirmBox(PeerData *recipient);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void confirmed(PeerData *recipient);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onConfirm();
|
||||||
|
|
||||||
|
private:
|
||||||
|
PeerData *_recipient;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class ConfirmLinkBox : public ConfirmBox {
|
class ConfirmLinkBox : public ConfirmBox {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -133,3 +153,100 @@ private:
|
||||||
anim::fvalue a_goodOpacity;
|
anim::fvalue a_goodOpacity;
|
||||||
Animation _a_good;
|
Animation _a_good;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConvertToSupergroupBox : public AbstractBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ConvertToSupergroupBox(ChatData *chat);
|
||||||
|
void keyPressEvent(QKeyEvent *e);
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onConvert();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void hideAll();
|
||||||
|
void showAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void convertDone(const MTPUpdates &updates);
|
||||||
|
bool convertFail(const RPCError &error);
|
||||||
|
|
||||||
|
ChatData *_chat;
|
||||||
|
Text _text, _note;
|
||||||
|
int32 _textWidth, _textHeight;
|
||||||
|
|
||||||
|
BoxButton _convert, _cancel;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PinMessageBox : public AbstractBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PinMessageBox(ChannelData *channel, MsgId msgId);
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onPin();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void showAll();
|
||||||
|
void hideAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void pinDone(const MTPUpdates &updates);
|
||||||
|
bool pinFail(const RPCError &error);
|
||||||
|
|
||||||
|
ChannelData *_channel;
|
||||||
|
MsgId _msgId;
|
||||||
|
|
||||||
|
FlatLabel _text;
|
||||||
|
Checkbox _notify;
|
||||||
|
|
||||||
|
BoxButton _pin, _cancel;
|
||||||
|
|
||||||
|
mtpRequestId _requestId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class RichDeleteMessageBox : public AbstractBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
RichDeleteMessageBox(ChannelData *channel, UserData *from, MsgId msgId);
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onDelete();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void showAll();
|
||||||
|
void hideAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ChannelData *_channel;
|
||||||
|
UserData *_from;
|
||||||
|
MsgId _msgId;
|
||||||
|
|
||||||
|
FlatLabel _text;
|
||||||
|
Checkbox _banUser, _reportSpam, _deleteAll;
|
||||||
|
|
||||||
|
BoxButton _delete, _cancel;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -201,8 +201,10 @@ void ConnectionBox::onSave() {
|
||||||
} else {
|
} else {
|
||||||
cSetConnectionType(dbictAuto);
|
cSetConnectionType(dbictAuto);
|
||||||
cSetConnectionProxy(ConnectionProxy());
|
cSetConnectionProxy(ConnectionProxy());
|
||||||
|
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (cPlatform() == dbipWindows && cTryIPv6() != _tryIPv6.checked()) {
|
if (cPlatform() == dbipWindows && cTryIPv6() != _tryIPv6.checked()) {
|
||||||
cSetTryIPv6(_tryIPv6.checked());
|
cSetTryIPv6(_tryIPv6.checked());
|
||||||
|
@ -313,9 +315,11 @@ void AutoDownloadBox::onSave() {
|
||||||
bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups));
|
bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups));
|
||||||
cSetAutoDownloadAudio(autoDownloadAudio);
|
cSetAutoDownloadAudio(autoDownloadAudio);
|
||||||
if (enabledPrivate || enabledGroups) {
|
if (enabledPrivate || enabledGroups) {
|
||||||
const AudiosData &data(App::audiosData());
|
const DocumentsData &data(App::documentsData());
|
||||||
for (AudiosData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
||||||
i.value()->automaticLoadSettingsChanged();
|
if (i.value()->voice()) {
|
||||||
|
i.value()->automaticLoadSettingsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -328,7 +332,9 @@ void AutoDownloadBox::onSave() {
|
||||||
if (enabledPrivate || enabledGroups) {
|
if (enabledPrivate || enabledGroups) {
|
||||||
const DocumentsData &data(App::documentsData());
|
const DocumentsData &data(App::documentsData());
|
||||||
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
||||||
i.value()->automaticLoadSettingsChanged();
|
if (i.value()->isAnimation()) {
|
||||||
|
i.value()->automaticLoadSettingsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Notify::automaticLoadSettingsChangedGif();
|
Notify::automaticLoadSettingsChangedGif();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -33,6 +33,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "confirmbox.h"
|
#include "confirmbox.h"
|
||||||
|
|
||||||
|
QString cantInviteError() {
|
||||||
|
return lng_cant_invite_not_contact(lt_more_info, textcmdLink(qsl("https://telegram.me/spambot"), lang(lng_cant_more_info)));
|
||||||
|
}
|
||||||
|
|
||||||
ContactsInner::ContactsInner(CreatingGroupType creating) : TWidget()
|
ContactsInner::ContactsInner(CreatingGroupType creating) : TWidget()
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
, _newItemHeight(creating == CreatingGroupNone ? st::contactsNewItemHeight : 0)
|
, _newItemHeight(creating == CreatingGroupNone ? st::contactsNewItemHeight : 0)
|
||||||
|
@ -224,7 +228,7 @@ void ContactsInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &old
|
||||||
|
|
||||||
void ContactsInner::onAddBot() {
|
void ContactsInner::onAddBot() {
|
||||||
if (_bot->botInfo && !_bot->botInfo->startGroupToken.isEmpty()) {
|
if (_bot->botInfo && !_bot->botInfo->startGroupToken.isEmpty()) {
|
||||||
MTP::send(MTPmessages_StartBot(_bot->inputUser, _addToPeer->input, MTP_long(MTP::nonce<uint64>()), MTP_string(_bot->botInfo->startGroupToken)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _bot));
|
MTP::send(MTPmessages_StartBot(_bot->inputUser, _addToPeer->input, MTP_long(rand_value<uint64>()), MTP_string(_bot->botInfo->startGroupToken)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _bot));
|
||||||
} else {
|
} else {
|
||||||
App::main()->addParticipants(_addToPeer, QVector<UserData*>(1, _bot));
|
App::main()->addParticipants(_addToPeer, QVector<UserData*>(1, _bot));
|
||||||
}
|
}
|
||||||
|
@ -257,6 +261,18 @@ void ContactsInner::addAdminDone(const MTPUpdates &result, mtpRequestId req) {
|
||||||
if (req != _addAdminRequestId) return;
|
if (req != _addAdminRequestId) return;
|
||||||
|
|
||||||
_addAdminRequestId = 0;
|
_addAdminRequestId = 0;
|
||||||
|
if (_addAdmin && _channel && _channel->isMegagroup()) {
|
||||||
|
if (_channel->mgInfo->lastParticipants.indexOf(_addAdmin) < 0) {
|
||||||
|
_channel->mgInfo->lastParticipants.push_front(_addAdmin);
|
||||||
|
}
|
||||||
|
_channel->mgInfo->lastAdmins.insert(_addAdmin);
|
||||||
|
if (_addAdmin->botInfo) {
|
||||||
|
_channel->mgInfo->bots.insert(_addAdmin);
|
||||||
|
if (_channel->mgInfo->botStatus != 0 && _channel->mgInfo->botStatus < 2) {
|
||||||
|
_channel->mgInfo->botStatus = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_addAdminBox) _addAdminBox->onClose();
|
if (_addAdminBox) _addAdminBox->onClose();
|
||||||
emit adminAdded();
|
emit adminAdded();
|
||||||
}
|
}
|
||||||
|
@ -272,6 +288,8 @@ bool ContactsInner::addAdminFail(const RPCError &error, mtpRequestId req) {
|
||||||
Ui::showLayer(new MaxInviteBox(_channel->invitationUrl), KeepOtherLayers);
|
Ui::showLayer(new MaxInviteBox(_channel->invitationUrl), KeepOtherLayers);
|
||||||
} else if (error.type() == "ADMINS_TOO_MUCH") {
|
} else if (error.type() == "ADMINS_TOO_MUCH") {
|
||||||
Ui::showLayer(new InformBox(lang(lng_channel_admins_too_much)), KeepOtherLayers);
|
Ui::showLayer(new InformBox(lang(lng_channel_admins_too_much)), KeepOtherLayers);
|
||||||
|
} else if (error.type() == qstr("USER_RESTRICTED")) {
|
||||||
|
Ui::showLayer(new InformBox(lang(lng_cant_do_this)), KeepOtherLayers);
|
||||||
} else {
|
} else {
|
||||||
emit adminAdded();
|
emit adminAdded();
|
||||||
}
|
}
|
||||||
|
@ -350,7 +368,7 @@ void ContactsInner::loadProfilePhotos(int32 yFrom) {
|
||||||
preloadFrom != _contacts->list.end && (_newItemHeight + preloadFrom->pos * _rowHeight) < yTo;
|
preloadFrom != _contacts->list.end && (_newItemHeight + preloadFrom->pos * _rowHeight) < yTo;
|
||||||
preloadFrom = preloadFrom->next
|
preloadFrom = preloadFrom->next
|
||||||
) {
|
) {
|
||||||
preloadFrom->history->peer->photo->load();
|
preloadFrom->history->peer->loadUserpic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!_filtered.isEmpty()) {
|
} else if (!_filtered.isEmpty()) {
|
||||||
|
@ -361,7 +379,7 @@ void ContactsInner::loadProfilePhotos(int32 yFrom) {
|
||||||
if (to > _filtered.size()) to = _filtered.size();
|
if (to > _filtered.size()) to = _filtered.size();
|
||||||
|
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
_filtered[from]->history->peer->photo->load();
|
_filtered[from]->history->peer->loadUserpic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,13 +445,13 @@ void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, b
|
||||||
sel = false;
|
sel = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (data->inchat || data->check || selectedCount() >= ((_channel && _channel->isMegagroup()) ? cMaxMegaGroupCount() : cMaxGroupCount())) {
|
if (data->inchat || data->check || selectedCount() >= Global::MegagroupSizeMax()) {
|
||||||
sel = false;
|
sel = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.fillRect(0, 0, width(), _rowHeight, inverse ? st::contactsBgActive : (sel ? st::contactsBgOver : st::white));
|
p.fillRect(0, 0, width(), _rowHeight, inverse ? st::contactsBgActive : (sel ? st::contactsBgOver : st::white));
|
||||||
p.setPen(inverse ? st::white : st::black);
|
p.setPen(inverse ? st::white : st::black);
|
||||||
p.drawPixmapLeft(st::contactsPadding.left(), st::contactsPadding.top(), width(), peer->photo->pix(st::contactsPhotoSize));
|
peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
||||||
|
|
||||||
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||||
int32 iconw = (_chat || _creating != CreatingGroupNone) ? (st::contactsCheckPosition.x() * 2 + st::contactsCheckIcon.pxWidth()) : 0;
|
int32 iconw = (_chat || _creating != CreatingGroupNone) ? (st::contactsCheckPosition.x() * 2 + st::contactsCheckIcon.pxWidth()) : 0;
|
||||||
|
@ -767,10 +785,14 @@ void ContactsInner::changeCheckState(ContactData *data, PeerData *peer) {
|
||||||
data->check = false;
|
data->check = false;
|
||||||
_checkedContacts.remove(peer);
|
_checkedContacts.remove(peer);
|
||||||
--_selCount;
|
--_selCount;
|
||||||
} else if (selectedCount() < ((_channel && _channel->isMegagroup()) ? cMaxMegaGroupCount() : cMaxGroupCount())) {
|
} else if (selectedCount() < ((_channel && _channel->isMegagroup()) ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) {
|
||||||
data->check = true;
|
data->check = true;
|
||||||
_checkedContacts.insert(peer, true);
|
_checkedContacts.insert(peer, true);
|
||||||
++_selCount;
|
++_selCount;
|
||||||
|
} else if (_channel && !_channel->isMegagroup()) {
|
||||||
|
Ui::showLayer(new MaxInviteBox(_channel->invitationUrl), KeepOtherLayers);
|
||||||
|
} else if (!_channel && selectedCount() >= Global::ChatSizeMax() && selectedCount() < Global::MegagroupSizeMax()) {
|
||||||
|
Ui::showLayer(new InformBox(lng_profile_add_more_after_upgrade(lt_count, Global::MegagroupSizeMax())), KeepOtherLayers);
|
||||||
}
|
}
|
||||||
if (cnt != _selCount) emit chosenChanged();
|
if (cnt != _selCount) emit chosenChanged();
|
||||||
}
|
}
|
||||||
|
@ -1535,7 +1557,7 @@ void ContactsBox::paintEvent(QPaintEvent *e) {
|
||||||
paintTitle(p, lang(lng_channel_admins));
|
paintTitle(p, lang(lng_channel_admins));
|
||||||
} else if (_inner.chat() || _inner.creating() != CreatingGroupNone) {
|
} else if (_inner.chat() || _inner.creating() != CreatingGroupNone) {
|
||||||
QString title(lang(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant));
|
QString title(lang(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant));
|
||||||
QString additional(addingAdmin ? QString() : QString("%1 / %2").arg(_inner.selectedCount()).arg(((_inner.channel() && _inner.channel()->isMegagroup()) ? cMaxMegaGroupCount() : cMaxGroupCount())));
|
QString additional((addingAdmin || (_inner.channel() && !_inner.channel()->isMegagroup())) ? QString() : QString("%1 / %2").arg(_inner.selectedCount()).arg(Global::MegagroupSizeMax()));
|
||||||
paintTitle(p, title, additional);
|
paintTitle(p, title, additional);
|
||||||
} else if (_inner.bot()) {
|
} else if (_inner.bot()) {
|
||||||
paintTitle(p, lang(lng_bot_choose_group));
|
paintTitle(p, lang(lng_bot_choose_group));
|
||||||
|
@ -1652,12 +1674,15 @@ void ContactsBox::getAdminsDone(const MTPmessages_ChatFull &result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_saveRequestId = 0;
|
_saveRequestId = 0;
|
||||||
for (ChatData::Admins::const_iterator i = curadmins.cbegin(), e = curadmins.cend(); i != e; ++i) {
|
|
||||||
MTP::send(MTPmessages_EditChatAdmin(_inner.chat()->inputChat, i.key()->inputUser, MTP_boolFalse()), rpcDone(&ContactsBox::removeAdminDone, i.key()), rpcFail(&ContactsBox::editAdminFail), 0, (appoint.isEmpty() && i + 1 == e) ? 0 : 10);
|
for_const (UserData *user, curadmins) {
|
||||||
|
MTP::send(MTPmessages_EditChatAdmin(_inner.chat()->inputChat, user->inputUser, MTP_boolFalse()), rpcDone(&ContactsBox::removeAdminDone, user), rpcFail(&ContactsBox::editAdminFail), 0, 10);
|
||||||
}
|
}
|
||||||
for (int32 i = 0, l = appoint.size(); i < l; ++i) {
|
for_const (UserData *user, appoint) {
|
||||||
MTP::send(MTPmessages_EditChatAdmin(_inner.chat()->inputChat, appoint.at(i)->inputUser, MTP_boolTrue()), rpcDone(&ContactsBox::setAdminDone, appoint.at(i)), rpcFail(&ContactsBox::editAdminFail), 0, (i + 1 == l) ? 0 : 10);
|
MTP::send(MTPmessages_EditChatAdmin(_inner.chat()->inputChat, user->inputUser, MTP_boolTrue()), rpcDone(&ContactsBox::setAdminDone, user), rpcFail(&ContactsBox::editAdminFail), 0, 10);
|
||||||
}
|
}
|
||||||
|
MTP::sendAnything();
|
||||||
|
|
||||||
_saveRequestId = curadmins.size() + appoint.size();
|
_saveRequestId = curadmins.size() + appoint.size();
|
||||||
if (!_saveRequestId) {
|
if (!_saveRequestId) {
|
||||||
onClose();
|
onClose();
|
||||||
|
@ -1669,7 +1694,7 @@ void ContactsBox::setAdminDone(UserData *user, const MTPBool &result) {
|
||||||
if (_inner.chat()->noParticipantInfo()) {
|
if (_inner.chat()->noParticipantInfo()) {
|
||||||
App::api()->requestFullPeer(_inner.chat());
|
App::api()->requestFullPeer(_inner.chat());
|
||||||
} else {
|
} else {
|
||||||
_inner.chat()->admins.insert(user, true);
|
_inner.chat()->admins.insert(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--_saveRequestId;
|
--_saveRequestId;
|
||||||
|
@ -1704,7 +1729,13 @@ bool ContactsBox::editAdminFail(const RPCError &error) {
|
||||||
if (mtpIsFlood(error)) return true;
|
if (mtpIsFlood(error)) return true;
|
||||||
--_saveRequestId;
|
--_saveRequestId;
|
||||||
_inner.chat()->invalidateParticipants();
|
_inner.chat()->invalidateParticipants();
|
||||||
if (!_saveRequestId) onClose();
|
if (!_saveRequestId) {
|
||||||
|
if (error.type() == qstr("USER_RESTRICTED")) {
|
||||||
|
Ui::showLayer(new InformBox(lang(lng_cant_do_this)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1749,7 +1780,10 @@ bool ContactsBox::creationFail(const RPCError &error) {
|
||||||
_filter.showError();
|
_filter.showError();
|
||||||
return true;
|
return true;
|
||||||
} else if (error.type() == "PEER_FLOOD") {
|
} else if (error.type() == "PEER_FLOOD") {
|
||||||
Ui::showLayer(new InformBox(lng_cant_invite_not_contact(lt_more_info, textcmdLink(qsl("https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts"), lang(lng_cant_more_info)))), KeepOtherLayers);
|
Ui::showLayer(new InformBox(cantInviteError()), KeepOtherLayers);
|
||||||
|
return true;
|
||||||
|
} else if (error.type() == qstr("USER_RESTRICTED")) {
|
||||||
|
Ui::showLayer(new InformBox(lang(lng_cant_do_this)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1757,7 +1791,7 @@ bool ContactsBox::creationFail(const RPCError &error) {
|
||||||
|
|
||||||
MembersInner::MembersInner(ChannelData *channel, MembersFilter filter) : TWidget()
|
MembersInner::MembersInner(ChannelData *channel, MembersFilter filter) : TWidget()
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
, _newItemHeight((channel->amCreator() && (channel->count < (channel->isMegagroup() ? cMaxMegaGroupCount() : cMaxGroupCount()) || (!channel->isMegagroup() && !channel->isPublic()) || filter == MembersFilterAdmins)) ? st::contactsNewItemHeight : 0)
|
, _newItemHeight((channel->amCreator() && (channel->count < (channel->isMegagroup() ? Global::MegagroupSizeMax() : Global::ChatSizeMax()) || (!channel->isMegagroup() && !channel->isPublic()) || filter == MembersFilterAdmins)) ? st::contactsNewItemHeight : 0)
|
||||||
, _newItemSel(false)
|
, _newItemSel(false)
|
||||||
, _channel(channel)
|
, _channel(channel)
|
||||||
, _filter(filter)
|
, _filter(filter)
|
||||||
|
@ -1787,7 +1821,7 @@ MembersInner::MembersInner(ChannelData *channel, MembersFilter filter) : TWidget
|
||||||
|
|
||||||
void MembersInner::load() {
|
void MembersInner::load() {
|
||||||
if (!_loadingRequestId) {
|
if (!_loadingRequestId) {
|
||||||
_loadingRequestId = MTP::send(MTPchannels_GetParticipants(_channel->inputChannel, (_filter == MembersFilterRecent) ? MTP_channelParticipantsRecent() : MTP_channelParticipantsAdmins(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&MembersInner::membersReceived), rpcFail(&MembersInner::membersFailed));
|
_loadingRequestId = MTP::send(MTPchannels_GetParticipants(_channel->inputChannel, (_filter == MembersFilterRecent) ? MTP_channelParticipantsRecent() : MTP_channelParticipantsAdmins(), MTP_int(0), MTP_int(Global::ChatSizeMax())), rpcDone(&MembersInner::membersReceived), rpcFail(&MembersInner::membersFailed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1826,7 +1860,7 @@ void MembersInner::paintEvent(QPaintEvent *e) {
|
||||||
paintDialog(p, _rows[from], data(from), sel, kickSel, kickDown);
|
paintDialog(p, _rows[from], data(from), sel, kickSel, kickDown);
|
||||||
p.translate(0, _rowHeight);
|
p.translate(0, _rowHeight);
|
||||||
}
|
}
|
||||||
if (to == _rows.size() && _filter == MembersFilterRecent && (_rows.size() < _channel->count || _rows.size() >= cMaxGroupCount())) {
|
if (to == _rows.size() && _filter == MembersFilterRecent && (_rows.size() < _channel->count || _rows.size() >= Global::ChatSizeMax())) {
|
||||||
p.setPen(st::stickersReorderFg);
|
p.setPen(st::stickersReorderFg);
|
||||||
_about.draw(p, st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, style::al_center);
|
_about.draw(p, st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, style::al_center);
|
||||||
}
|
}
|
||||||
|
@ -1895,7 +1929,7 @@ void MembersInner::paintDialog(Painter &p, PeerData *peer, MemberData *data, boo
|
||||||
UserData *user = peer->asUser();
|
UserData *user = peer->asUser();
|
||||||
|
|
||||||
p.fillRect(0, 0, width(), _rowHeight, (sel ? st::contactsBgOver : st::white)->b);
|
p.fillRect(0, 0, width(), _rowHeight, (sel ? st::contactsBgOver : st::white)->b);
|
||||||
p.drawPixmapLeft(st::contactsPadding.left(), st::contactsPadding.top(), width(), peer->photo->pix(st::contactsPhotoSize));
|
peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
||||||
|
|
||||||
p.setPen(st::black);
|
p.setPen(st::black);
|
||||||
|
|
||||||
|
@ -1980,7 +2014,7 @@ void MembersInner::loadProfilePhotos(int32 yFrom) {
|
||||||
if (to > _rows.size()) to = _rows.size();
|
if (to > _rows.size()) to = _rows.size();
|
||||||
|
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
_rows[from]->photo->load();
|
_rows[from]->loadUserpic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2005,7 +2039,7 @@ void MembersInner::refresh() {
|
||||||
} else {
|
} else {
|
||||||
_about.setText(st::boxTextFont, lng_channel_only_last_shown(lt_count, _rows.size()));
|
_about.setText(st::boxTextFont, lng_channel_only_last_shown(lt_count, _rows.size()));
|
||||||
_aboutHeight = st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom();
|
_aboutHeight = st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom();
|
||||||
if (_filter != MembersFilterRecent || (_rows.size() >= _channel->count && _rows.size() < cMaxGroupCount())) {
|
if (_filter != MembersFilterRecent || (_rows.size() >= _channel->count && _rows.size() < Global::ChatSizeMax())) {
|
||||||
_aboutHeight = 0;
|
_aboutHeight = 0;
|
||||||
}
|
}
|
||||||
resize(width(), st::membersPadding.top() + _newItemHeight + _rows.size() * _rowHeight + st::membersPadding.bottom() + _aboutHeight);
|
resize(width(), st::membersPadding.top() + _newItemHeight + _rows.size() * _rowHeight + st::membersPadding.bottom() + _aboutHeight);
|
||||||
|
@ -2182,6 +2216,16 @@ void MembersInner::membersReceived(const MTPchannels_ChannelParticipants &result
|
||||||
_datas.push_back(0);
|
_datas.push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update admins if we got all of them
|
||||||
|
if (_filter == MembersFilterAdmins && _channel->isMegagroup() && _rows.size() < Global::ChatSizeMax()) {
|
||||||
|
_channel->mgInfo->lastAdmins.clear();
|
||||||
|
for (int32 i = 0, l = _rows.size(); i != l; ++i) {
|
||||||
|
if (_roles.at(i) == MemberRoleCreator || _roles.at(i) == MemberRoleEditor) {
|
||||||
|
_channel->mgInfo->lastAdmins.insert(_rows.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_rows.isEmpty()) {
|
if (_rows.isEmpty()) {
|
||||||
_rows.push_back(App::self());
|
_rows.push_back(App::self());
|
||||||
|
@ -2297,7 +2341,7 @@ void MembersBox::onScroll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MembersBox::onAdd() {
|
void MembersBox::onAdd() {
|
||||||
if (_inner.filter() == MembersFilterRecent && _inner.channel()->count >= (_inner.channel()->isMegagroup() ? cMaxMegaGroupCount() : cMaxGroupCount())) {
|
if (_inner.filter() == MembersFilterRecent && _inner.channel()->count >= (_inner.channel()->isMegagroup() ? Global::MegagroupSizeMax() : Global::ChatSizeMax())) {
|
||||||
Ui::showLayer(new MaxInviteBox(_inner.channel()->invitationUrl), KeepOtherLayers);
|
Ui::showLayer(new MaxInviteBox(_inner.channel()->invitationUrl), KeepOtherLayers);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ enum MembersFilter {
|
||||||
};
|
};
|
||||||
typedef QMap<UserData*, bool> MembersAlreadyIn;
|
typedef QMap<UserData*, bool> MembersAlreadyIn;
|
||||||
|
|
||||||
|
QString cantInviteError();
|
||||||
|
|
||||||
class ConfirmBox;
|
class ConfirmBox;
|
||||||
class ContactsInner : public TWidget, public RPCSender {
|
class ContactsInner : public TWidget, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -46,12 +46,12 @@ _close(this, lang(lng_box_ok), st::defaultBoxButton) {
|
||||||
for (int32 i = 0; i < languageCount; ++i) {
|
for (int32 i = 0; i < languageCount; ++i) {
|
||||||
LangLoaderResult result;
|
LangLoaderResult result;
|
||||||
if (i) {
|
if (i) {
|
||||||
LangLoaderPlain loader(qsl(":/langs/lang_") + LanguageCodes[i] + qsl(".strings"), LangLoaderRequest(lng_language_name));
|
LangLoaderPlain loader(qsl(":/langs/lang_") + LanguageCodes[i].c_str() + qsl(".strings"), LangLoaderRequest(lng_language_name));
|
||||||
result = loader.found();
|
result = loader.found();
|
||||||
} else {
|
} else {
|
||||||
result.insert(lng_language_name, langOriginal(lng_language_name));
|
result.insert(lng_language_name, langOriginal(lng_language_name));
|
||||||
}
|
}
|
||||||
_langs.push_back(new Radiobutton(this, qsl("lang"), i, result.value(lng_language_name, LanguageCodes[i] + qsl(" language")), (cLang() == i), st::langsButton));
|
_langs.push_back(new Radiobutton(this, qsl("lang"), i, result.value(lng_language_name, LanguageCodes[i].c_str() + qsl(" language")), (cLang() == i), st::langsButton));
|
||||||
_langs.back()->move(st::boxPadding.left() + st::boxOptionListPadding.left(), y);
|
_langs.back()->move(st::boxPadding.left() + st::boxOptionListPadding.left(), y);
|
||||||
y += _langs.back()->height() + st::boxOptionListPadding.top();
|
y += _langs.back()->height() + st::boxOptionListPadding.top();
|
||||||
connect(_langs.back(), SIGNAL(changed()), this, SLOT(onChange()));
|
connect(_langs.back(), SIGNAL(changed()), this, SLOT(onChange()));
|
||||||
|
@ -82,14 +82,14 @@ void LanguageBox::showAll() {
|
||||||
void LanguageBox::mousePressEvent(QMouseEvent *e) {
|
void LanguageBox::mousePressEvent(QMouseEvent *e) {
|
||||||
if ((e->modifiers() & Qt::CTRL) && (e->modifiers() & Qt::ALT) && (e->modifiers() & Qt::SHIFT)) {
|
if ((e->modifiers() & Qt::CTRL) && (e->modifiers() & Qt::ALT) && (e->modifiers() & Qt::SHIFT)) {
|
||||||
for (int32 i = 1; i < languageCount; ++i) {
|
for (int32 i = 1; i < languageCount; ++i) {
|
||||||
LangLoaderPlain loader(qsl(":/langs/lang_") + LanguageCodes[i] + qsl(".strings"), LangLoaderRequest(lngkeys_cnt));
|
LangLoaderPlain loader(qsl(":/langs/lang_") + LanguageCodes[i].c_str() + qsl(".strings"), LangLoaderRequest(lngkeys_cnt));
|
||||||
if (!loader.errors().isEmpty()) {
|
if (!loader.errors().isEmpty()) {
|
||||||
Ui::showLayer(new InformBox(qsl("Lang \"") + LanguageCodes[i] + qsl("\" error :(\n\nError: ") + loader.errors()));
|
Ui::showLayer(new InformBox(qsl("Lang \"") + LanguageCodes[i].c_str() + qsl("\" error :(\n\nError: ") + loader.errors()));
|
||||||
return;
|
return;
|
||||||
} else if (!loader.warnings().isEmpty()) {
|
} else if (!loader.warnings().isEmpty()) {
|
||||||
QString warn = loader.warnings();
|
QString warn = loader.warnings();
|
||||||
if (warn.size() > 256) warn = warn.mid(0, 254) + qsl("..");
|
if (warn.size() > 256) warn = warn.mid(0, 253) + qsl("...");
|
||||||
Ui::showLayer(new InformBox(qsl("Lang \"") + LanguageCodes[i] + qsl("\" warnings :(\n\nWarnings: ") + warn));
|
Ui::showLayer(new InformBox(qsl("Lang \"") + LanguageCodes[i].c_str() + qsl("\" warnings :(\n\nWarnings: ") + warn));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ void LanguageBox::onChange() {
|
||||||
if (_langs[i]->checked() && langId != cLang()) {
|
if (_langs[i]->checked() && langId != cLang()) {
|
||||||
LangLoaderResult result;
|
LangLoaderResult result;
|
||||||
if (langId > 0) {
|
if (langId > 0) {
|
||||||
LangLoaderPlain loader(qsl(":/langs/lang_") + LanguageCodes[langId] + qsl(".strings"), LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_box_ok));
|
LangLoaderPlain loader(qsl(":/langs/lang_") + LanguageCodes[langId].c_str() + qsl(".strings"), LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_box_ok));
|
||||||
result = loader.found();
|
result = loader.found();
|
||||||
} else if (langId == languageTest) {
|
} else if (langId == languageTest) {
|
||||||
LangLoaderPlain loader(cLangFile(), LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_box_ok));
|
LangLoaderPlain loader(cLangFile(), LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_box_ok));
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -400,12 +400,12 @@ void PasscodeBox::onSave(bool force) {
|
||||||
if (!_oldPasscode.isHidden()) {
|
if (!_oldPasscode.isHidden()) {
|
||||||
hashSha256(oldPasswordData.constData(), oldPasswordData.size(), oldPasswordHash.data());
|
hashSha256(oldPasswordData.constData(), oldPasswordData.size(), oldPasswordHash.data());
|
||||||
}
|
}
|
||||||
int32 flags = MTPDaccount_passwordInputSettings::flag_new_salt | MTPDaccount_passwordInputSettings::flag_new_password_hash | MTPDaccount_passwordInputSettings::flag_hint;
|
MTPDaccount_passwordInputSettings::Flags flags = MTPDaccount_passwordInputSettings::Flag::f_new_salt | MTPDaccount_passwordInputSettings::Flag::f_new_password_hash | MTPDaccount_passwordInputSettings::Flag::f_hint;
|
||||||
if (_oldPasscode.isHidden() || _newPasscode.isHidden()) {
|
if (_oldPasscode.isHidden() || _newPasscode.isHidden()) {
|
||||||
flags |= MTPDaccount_passwordInputSettings::flag_email;
|
flags |= MTPDaccount_passwordInputSettings::Flag::f_email;
|
||||||
}
|
}
|
||||||
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_int(flags), MTP_string(_newSalt), MTP_string(newPasswordHash), MTP_string(hint), MTP_string(email)));
|
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_bytes(_newSalt), MTP_bytes(newPasswordHash), MTP_string(hint), MTP_string(email)));
|
||||||
_setRequest = MTP::send(MTPaccount_UpdatePasswordSettings(MTP_string(oldPasswordHash), settings), rpcDone(&PasscodeBox::setPasswordDone), rpcFail(&PasscodeBox::setPasswordFail));
|
_setRequest = MTP::send(MTPaccount_UpdatePasswordSettings(MTP_bytes(oldPasswordHash), settings), rpcDone(&PasscodeBox::setPasswordDone), rpcFail(&PasscodeBox::setPasswordFail));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cSetPasscodeBadTries(0);
|
cSetPasscodeBadTries(0);
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "style.h"
|
#include "gui/style.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "style.h"
|
#include "gui/style.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
@ -69,8 +69,8 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
|
||||||
if (_animated) {
|
if (_animated) {
|
||||||
int32 limitW = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
int32 limitW = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
||||||
int32 limitH = st::confirmMaxHeight;
|
int32 limitH = st::confirmMaxHeight;
|
||||||
maxW = dimensions.width();
|
maxW = qMax(dimensions.width(), 1);
|
||||||
maxH = dimensions.height();
|
maxH = qMax(dimensions.height(), 1);
|
||||||
if (maxW * limitH > maxH * limitW) {
|
if (maxW * limitH > maxH * limitW) {
|
||||||
if (maxW < limitW) {
|
if (maxW < limitW) {
|
||||||
maxH = maxH * limitW / maxW;
|
maxH = maxH * limitW / maxW;
|
||||||
|
@ -82,7 +82,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
|
||||||
maxH = limitH;
|
maxH = limitH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_thumb = imagePix(_file->thumb.toImage(), maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), true, true, false, maxW, maxH);
|
_thumb = imagePix(_file->thumb.toImage(), maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth | ImagePixBlurred, maxW, maxH);
|
||||||
} else {
|
} else {
|
||||||
for (PreparedPhotoThumbs::const_iterator i = _file->photoThumbs.cbegin(), e = _file->photoThumbs.cend(); i != e; ++i) {
|
for (PreparedPhotoThumbs::const_iterator i = _file->photoThumbs.cbegin(), e = _file->photoThumbs.cend(); i != e; ++i) {
|
||||||
if (i->width() >= maxW && i->height() >= maxH) {
|
if (i->width() >= maxW && i->height() >= maxH) {
|
||||||
|
@ -124,7 +124,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
|
||||||
} else {
|
} else {
|
||||||
_thumbw = st::msgFileThumbSize;
|
_thumbw = st::msgFileThumbSize;
|
||||||
}
|
}
|
||||||
_thumb = imagePix(_thumb.toImage(), _thumbw * cIntRetinaFactor(), 0, true, false, true, st::msgFileThumbSize, st::msgFileThumbSize);
|
_thumb = imagePix(_thumb.toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRounded, st::msgFileThumbSize, st::msgFileThumbSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
_name.setText(st::semiboldFont, _file->filename, _textNameOptions);
|
_name.setText(st::semiboldFont, _file->filename, _textNameOptions);
|
||||||
|
@ -274,7 +274,7 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
p.drawSpriteCenter(inner, _isImage ? st::msgFileOutImage : st::msgFileOutFile);
|
p.drawSpriteCenter(inner, _isImage ? st::msgFileOutImage : st::msgFileOutFile);
|
||||||
} else {
|
} else {
|
||||||
p.drawPixmapLeft(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), userDefPhoto(1)->pixRounded(st::msgFileSize));
|
p.drawPixmapLeft(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), userDefPhoto(1)->pixCircled(st::msgFileSize));
|
||||||
}
|
}
|
||||||
p.setFont(st::semiboldFont);
|
p.setFont(st::semiboldFont);
|
||||||
p.setPen(st::black);
|
p.setPen(st::black);
|
||||||
|
@ -359,3 +359,330 @@ void PhotoSendBox::onSend(bool ctrlShiftEnter) {
|
||||||
_confirmed = true;
|
_confirmed = true;
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditCaptionBox::EditCaptionBox(HistoryItem *msg) : AbstractBox(st::boxWideWidth)
|
||||||
|
, _msgId(msg->fullId())
|
||||||
|
, _animated(false)
|
||||||
|
, _photo(false)
|
||||||
|
, _doc(false)
|
||||||
|
, _field(0)
|
||||||
|
, _save(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||||
|
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||||
|
, _thumbx(0)
|
||||||
|
, _thumby(0)
|
||||||
|
, _thumbw(0)
|
||||||
|
, _thumbh(0)
|
||||||
|
, _statusw(0)
|
||||||
|
, _isImage(false)
|
||||||
|
, _previewCancelled(false)
|
||||||
|
, _saveRequestId(0) {
|
||||||
|
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||||
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
|
|
||||||
|
QSize dimensions;
|
||||||
|
ImagePtr image;
|
||||||
|
QString caption;
|
||||||
|
DocumentData *doc = 0;
|
||||||
|
if (HistoryMedia *media = msg->getMedia()) {
|
||||||
|
HistoryMediaType t = media->type();
|
||||||
|
switch (t) {
|
||||||
|
case MediaTypeGif: {
|
||||||
|
_animated = true;
|
||||||
|
doc = static_cast<HistoryGif*>(media)->getDocument();
|
||||||
|
dimensions = doc->dimensions;
|
||||||
|
image = doc->thumb;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MediaTypePhoto: {
|
||||||
|
_photo = true;
|
||||||
|
PhotoData *photo = static_cast<HistoryPhoto*>(media)->photo();
|
||||||
|
dimensions = QSize(photo->full->width(), photo->full->height());
|
||||||
|
image = photo->full;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MediaTypeVideo: {
|
||||||
|
_animated = true;
|
||||||
|
doc = static_cast<HistoryVideo*>(media)->getDocument();
|
||||||
|
dimensions = doc->dimensions;
|
||||||
|
image = doc->thumb;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MediaTypeFile:
|
||||||
|
case MediaTypeMusicFile:
|
||||||
|
case MediaTypeVoiceFile: {
|
||||||
|
_doc = true;
|
||||||
|
doc = static_cast<HistoryDocument*>(media)->getDocument();
|
||||||
|
image = doc->thumb;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
caption = media->getCaption();
|
||||||
|
}
|
||||||
|
if ((!_animated && (dimensions.isEmpty() || doc)) || image->isNull()) {
|
||||||
|
_animated = false;
|
||||||
|
if (image->isNull()) {
|
||||||
|
_thumbw = 0;
|
||||||
|
} else {
|
||||||
|
int32 tw = image->width(), th = image->height();
|
||||||
|
if (tw > th) {
|
||||||
|
_thumbw = (tw * st::msgFileThumbSize) / th;
|
||||||
|
} else {
|
||||||
|
_thumbw = st::msgFileThumbSize;
|
||||||
|
}
|
||||||
|
_thumb = imagePix(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRounded, st::msgFileThumbSize, st::msgFileThumbSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc) {
|
||||||
|
if (doc->voice()) {
|
||||||
|
_name.setText(st::semiboldFont, lang(lng_media_audio), _textNameOptions);
|
||||||
|
} else {
|
||||||
|
_name.setText(st::semiboldFont, documentName(doc), _textNameOptions);
|
||||||
|
}
|
||||||
|
_status = formatSizeText(doc->size);
|
||||||
|
_statusw = qMax(_name.maxWidth(), st::normalFont->width(_status));
|
||||||
|
_isImage = doc->isImage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int32 maxW = 0, maxH = 0;
|
||||||
|
if (_animated) {
|
||||||
|
int32 limitW = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
||||||
|
int32 limitH = st::confirmMaxHeight;
|
||||||
|
maxW = qMax(dimensions.width(), 1);
|
||||||
|
maxH = qMax(dimensions.height(), 1);
|
||||||
|
if (maxW * limitH > maxH * limitW) {
|
||||||
|
if (maxW < limitW) {
|
||||||
|
maxH = maxH * limitW / maxW;
|
||||||
|
maxW = limitW;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (maxH < limitH) {
|
||||||
|
maxW = maxW * limitH / maxH;
|
||||||
|
maxH = limitH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth | ImagePixBlurred, maxW, maxH);
|
||||||
|
} else {
|
||||||
|
maxW = dimensions.width();
|
||||||
|
maxH = dimensions.height();
|
||||||
|
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth | ImagePixRounded, maxW, maxH);
|
||||||
|
}
|
||||||
|
int32 tw = _thumb.width(), th = _thumb.height();
|
||||||
|
if (!tw || !th) {
|
||||||
|
tw = th = 1;
|
||||||
|
}
|
||||||
|
_thumbw = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
||||||
|
if (_thumb.width() < _thumbw) {
|
||||||
|
_thumbw = (_thumb.width() > 20) ? _thumb.width() : 20;
|
||||||
|
}
|
||||||
|
int32 maxthumbh = qMin(qRound(1.5 * _thumbw), int(st::confirmMaxHeight));
|
||||||
|
_thumbh = qRound(th * float64(_thumbw) / tw);
|
||||||
|
if (_thumbh > maxthumbh) {
|
||||||
|
_thumbw = qRound(_thumbw * float64(maxthumbh) / _thumbh);
|
||||||
|
_thumbh = maxthumbh;
|
||||||
|
if (_thumbw < 10) {
|
||||||
|
_thumbw = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_thumbx = (width() - _thumbw) / 2;
|
||||||
|
|
||||||
|
_thumb = QPixmap::fromImage(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly);
|
||||||
|
_thumb.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_animated || _photo || _doc) {
|
||||||
|
_field = new InputArea(this, st::confirmCaptionArea, lang(lng_photo_caption), caption);
|
||||||
|
_field->setMaxLength(MaxPhotoCaption);
|
||||||
|
_field->setCtrlEnterSubmit(CtrlEnterSubmitBoth);
|
||||||
|
} else {
|
||||||
|
QString text = textApplyEntities(msg->originalText(), msg->originalEntities());
|
||||||
|
_field = new InputArea(this, st::editTextArea, lang(lng_photo_caption), text);
|
||||||
|
// _field->setMaxLength(MaxMessageSize); // entities can make text in input field larger but still valid
|
||||||
|
_field->setCtrlEnterSubmit(cCtrlEnter() ? CtrlEnterSubmitCtrlEnter : CtrlEnterSubmitEnter);
|
||||||
|
}
|
||||||
|
updateBoxSize();
|
||||||
|
connect(_field, SIGNAL(submitted(bool)), this, SLOT(onSave(bool)));
|
||||||
|
connect(_field, SIGNAL(cancelled()), this, SLOT(onClose()));
|
||||||
|
connect(_field, SIGNAL(resized()), this, SLOT(onCaptionResized()));
|
||||||
|
|
||||||
|
QTextCursor c(_field->textCursor());
|
||||||
|
c.movePosition(QTextCursor::End);
|
||||||
|
_field->setTextCursor(c);
|
||||||
|
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditCaptionBox::captionFound() const {
|
||||||
|
return _animated || _photo || _doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::onCaptionResized() {
|
||||||
|
updateBoxSize();
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::updateBoxSize() {
|
||||||
|
int32 bottomh = st::boxPhotoCompressedPadding.bottom() + _field->height() + st::normalFont->height + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom();
|
||||||
|
if (_photo || _animated) {
|
||||||
|
setMaxHeight(st::boxPhotoPadding.top() + _thumbh + bottomh);
|
||||||
|
} else if (_thumbw) {
|
||||||
|
setMaxHeight(st::boxPhotoPadding.top() + 0 + st::msgFileThumbSize + 0 + bottomh);
|
||||||
|
} else if (_doc) {
|
||||||
|
setMaxHeight(st::boxPhotoPadding.top() + 0 + st::msgFileSize + 0 + bottomh);
|
||||||
|
} else {
|
||||||
|
setMaxHeight(st::boxPhotoPadding.top() + st::boxTitleFont->height + bottomh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
if (paint(p)) return;
|
||||||
|
|
||||||
|
if (_photo || _animated) {
|
||||||
|
if (_thumbx > st::boxPhotoPadding.left()) {
|
||||||
|
p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _thumbx - st::boxPhotoPadding.left(), _thumbh, st::confirmBg->b);
|
||||||
|
}
|
||||||
|
if (_thumbx + _thumbw < width() - st::boxPhotoPadding.right()) {
|
||||||
|
p.fillRect(_thumbx + _thumbw, st::boxPhotoPadding.top(), width() - st::boxPhotoPadding.right() - _thumbx - _thumbw, _thumbh, st::confirmBg->b);
|
||||||
|
}
|
||||||
|
p.drawPixmap(_thumbx, st::boxPhotoPadding.top(), _thumb);
|
||||||
|
if (_animated) {
|
||||||
|
QRect inner(_thumbx + (_thumbw - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (_thumbh - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st::msgDateImgBg);
|
||||||
|
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||||
|
p.drawEllipse(inner);
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||||
|
|
||||||
|
p.drawSpriteCenter(inner, st::msgFileInPlay);
|
||||||
|
}
|
||||||
|
} else if (_doc) {
|
||||||
|
int32 w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
||||||
|
int32 h = _thumbw ? (0 + st::msgFileThumbSize + 0) : (0 + st::msgFileSize + 0);
|
||||||
|
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0;
|
||||||
|
if (_thumbw) {
|
||||||
|
nameleft = 0 + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
||||||
|
nametop = st::msgFileThumbNameTop - st::msgFileThumbPadding.top();
|
||||||
|
nameright = 0;
|
||||||
|
statustop = st::msgFileThumbStatusTop - st::msgFileThumbPadding.top();
|
||||||
|
} else {
|
||||||
|
nameleft = 0 + st::msgFileSize + st::msgFilePadding.right();
|
||||||
|
nametop = st::msgFileNameTop - st::msgFilePadding.top();
|
||||||
|
nameright = 0;
|
||||||
|
statustop = st::msgFileStatusTop - st::msgFilePadding.top();
|
||||||
|
}
|
||||||
|
int32 namewidth = w - nameleft - 0;
|
||||||
|
if (namewidth > _statusw) {
|
||||||
|
//w -= (namewidth - _statusw);
|
||||||
|
//namewidth = _statusw;
|
||||||
|
}
|
||||||
|
int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top();
|
||||||
|
|
||||||
|
// App::roundRect(p, x, y, w, h, st::msgInBg, MessageInCorners, &st::msgInShadow);
|
||||||
|
|
||||||
|
if (_thumbw) {
|
||||||
|
QRect rthumb(rtlrect(x + 0, y + 0, st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
||||||
|
p.drawPixmap(rthumb.topLeft(), _thumb);
|
||||||
|
} else {
|
||||||
|
QRect inner(rtlrect(x + 0, y + 0, st::msgFileSize, st::msgFileSize, width()));
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st::msgFileInBg);
|
||||||
|
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||||
|
p.drawEllipse(inner);
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||||
|
|
||||||
|
p.drawSpriteCenter(inner, _isImage ? st::msgFileInImage : st::msgFileInFile);
|
||||||
|
}
|
||||||
|
p.setFont(st::semiboldFont);
|
||||||
|
p.setPen(st::black);
|
||||||
|
_name.drawLeftElided(p, x + nameleft, y + nametop, namewidth, width());
|
||||||
|
|
||||||
|
style::color status(st::mediaInFg);
|
||||||
|
p.setFont(st::normalFont);
|
||||||
|
p.setPen(status);
|
||||||
|
p.drawTextLeft(x + nameleft, y + statustop, width(), _status);
|
||||||
|
} else {
|
||||||
|
p.setFont(st::boxTitleFont);
|
||||||
|
p.setPen(st::black);
|
||||||
|
p.drawTextLeft(_field->x(), st::boxPhotoPadding.top(), width(), lang(lng_edit_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_error.isEmpty()) {
|
||||||
|
p.setFont(st::normalFont);
|
||||||
|
p.setPen(st::setErrColor);
|
||||||
|
p.drawTextLeft(_field->x(), _field->y() + _field->height() + (st::boxButtonPadding.top() / 2), width(), _error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
|
||||||
|
_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());
|
||||||
|
_field->resize(st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), _field->height());
|
||||||
|
_field->moveToLeft(st::boxPhotoPadding.left(), _save.y() - st::boxButtonPadding.top() - st::normalFont->height - _field->height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::hideAll() {
|
||||||
|
_save.hide();
|
||||||
|
_cancel.hide();
|
||||||
|
_field->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::showAll() {
|
||||||
|
_save.show();
|
||||||
|
_cancel.show();
|
||||||
|
_field->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::showDone() {
|
||||||
|
setInnerFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::onSave(bool ctrlShiftEnter) {
|
||||||
|
if (_saveRequestId) return;
|
||||||
|
|
||||||
|
HistoryItem *item = App::histItemById(_msgId);
|
||||||
|
if (!item) {
|
||||||
|
_error = lang(lng_edit_deleted);
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPmessages_EditMessage::Flags flags = 0;
|
||||||
|
if (_previewCancelled) {
|
||||||
|
flags |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
||||||
|
}
|
||||||
|
MTPVector<MTPMessageEntity> sentEntities;
|
||||||
|
if (!sentEntities.c_vector().v.isEmpty()) {
|
||||||
|
flags |= MTPmessages_EditMessage::Flag::f_entities;
|
||||||
|
}
|
||||||
|
_saveRequestId = MTP::send(MTPmessages_EditMessage(MTP_flags(flags), item->history()->peer->input, MTP_int(item->id), MTP_string(_field->getLastText()), MTPnullMarkup, sentEntities), rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditCaptionBox::saveDone(const MTPUpdates &updates) {
|
||||||
|
_saveRequestId = 0;
|
||||||
|
onClose();
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->sentUpdatesReceived(updates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditCaptionBox::saveFail(const RPCError &error) {
|
||||||
|
if (mtpIsFlood(error)) return false;
|
||||||
|
|
||||||
|
_saveRequestId = 0;
|
||||||
|
QString err = error.type();
|
||||||
|
if (err == qstr("MESSAGE_ID_INVALID") || err == qstr("CHAT_ADMIN_REQUIRED") || err == qstr("MESSAGE_EDIT_TIME_EXPIRED")) {
|
||||||
|
_error = lang(lng_edit_error);
|
||||||
|
} else if (err == qstr("MESSAGE_NOT_MODIFIED")) {
|
||||||
|
onClose();
|
||||||
|
return true;
|
||||||
|
} else if (err == qstr("MESSAGE_EMPTY")) {
|
||||||
|
_field->setFocus();
|
||||||
|
_field->showError();
|
||||||
|
} else {
|
||||||
|
_error = lang(lng_edit_error);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -42,11 +42,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
void confirmed();
|
|
||||||
void cancelled();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onCompressedChange();
|
void onCompressedChange();
|
||||||
|
@ -87,3 +82,57 @@ private:
|
||||||
bool _confirmed;
|
bool _confirmed;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EditCaptionBox : public AbstractBox, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EditCaptionBox(HistoryItem *msg);
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
|
bool captionFound() const;
|
||||||
|
|
||||||
|
void setInnerFocus() {
|
||||||
|
_field->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onCaptionResized();
|
||||||
|
void onSave(bool ctrlShiftEnter = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void hideAll();
|
||||||
|
void showAll();
|
||||||
|
void showDone();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateBoxSize();
|
||||||
|
|
||||||
|
void saveDone(const MTPUpdates &updates);
|
||||||
|
bool saveFail(const RPCError &error);
|
||||||
|
|
||||||
|
FullMsgId _msgId;
|
||||||
|
bool _animated, _photo, _doc;
|
||||||
|
|
||||||
|
QPixmap _thumb;
|
||||||
|
|
||||||
|
InputArea *_field;
|
||||||
|
BoxButton _save, _cancel;
|
||||||
|
|
||||||
|
int32 _thumbx, _thumby, _thumbw, _thumbh;
|
||||||
|
Text _name;
|
||||||
|
QString _status;
|
||||||
|
int32 _statusw;
|
||||||
|
bool _isImage;
|
||||||
|
|
||||||
|
bool _previewCancelled;
|
||||||
|
mtpRequestId _saveRequestId;
|
||||||
|
|
||||||
|
QString _error;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -29,9 +29,17 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) :
|
StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : TWidget()
|
||||||
_loaded(false), _setId(0), _setAccess(0), _setCount(0), _setHash(0), _setFlags(0), _bottom(0),
|
, _loaded(false)
|
||||||
_input(set), _installRequest(0) {
|
, _setId(0)
|
||||||
|
, _setAccess(0)
|
||||||
|
, _setCount(0)
|
||||||
|
, _setHash(0)
|
||||||
|
, _setFlags(0)
|
||||||
|
, _bottom(0)
|
||||||
|
, _input(set)
|
||||||
|
, _installRequest(0)
|
||||||
|
, _previewShown(-1) {
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
switch (set.type()) {
|
switch (set.type()) {
|
||||||
case mtpc_inputStickerSetID: _setId = set.c_inputStickerSetID().vid.v; _setAccess = set.c_inputStickerSetID().vaccess_hash.v; break;
|
case mtpc_inputStickerSetID: _setId = set.c_inputStickerSetID().vid.v; _setAccess = set.c_inputStickerSetID().vaccess_hash.v; break;
|
||||||
|
@ -39,10 +47,14 @@ _input(set), _installRequest(0) {
|
||||||
}
|
}
|
||||||
MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet));
|
MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet));
|
||||||
App::main()->updateStickers();
|
App::main()->updateStickers();
|
||||||
|
|
||||||
|
_previewTimer.setSingleShot(true);
|
||||||
|
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||||
_pack.clear();
|
_pack.clear();
|
||||||
|
_emoji.clear();
|
||||||
if (set.type() == mtpc_messages_stickerSet) {
|
if (set.type() == mtpc_messages_stickerSet) {
|
||||||
const MTPDmessages_stickerSet &d(set.c_messages_stickerSet());
|
const MTPDmessages_stickerSet &d(set.c_messages_stickerSet());
|
||||||
const QVector<MTPDocument> &v(d.vdocuments.c_vector().v);
|
const QVector<MTPDocument> &v(d.vdocuments.c_vector().v);
|
||||||
|
@ -53,6 +65,23 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||||
|
|
||||||
_pack.push_back(doc);
|
_pack.push_back(doc);
|
||||||
}
|
}
|
||||||
|
const QVector<MTPStickerPack> &packs(d.vpacks.c_vector().v);
|
||||||
|
for (int32 i = 0, l = packs.size(); i < l; ++i) {
|
||||||
|
if (packs.at(i).type() != mtpc_stickerPack) continue;
|
||||||
|
const MTPDstickerPack &pack(packs.at(i).c_stickerPack());
|
||||||
|
if (EmojiPtr e = emojiGetNoColor(emojiFromText(qs(pack.vemoticon)))) {
|
||||||
|
const QVector<MTPlong> &stickers(pack.vdocuments.c_vector().v);
|
||||||
|
StickerPack p;
|
||||||
|
p.reserve(stickers.size());
|
||||||
|
for (int32 j = 0, c = stickers.size(); j < c; ++j) {
|
||||||
|
DocumentData *doc = App::document(stickers.at(j).v);
|
||||||
|
if (!doc || !doc->sticker()) continue;
|
||||||
|
|
||||||
|
p.push_back(doc);
|
||||||
|
}
|
||||||
|
_emoji.insert(e, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (d.vset.type() == mtpc_stickerSet) {
|
if (d.vset.type() == mtpc_stickerSet) {
|
||||||
const MTPDstickerSet &s(d.vset.c_stickerSet());
|
const MTPDstickerSet &s(d.vset.c_stickerSet());
|
||||||
_setTitle = stickerSetTitle(s);
|
_setTitle = stickerSetTitle(s);
|
||||||
|
@ -88,12 +117,17 @@ bool StickerSetInner::failedSet(const RPCError &error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerSetInner::installDone(const MTPBool &result) {
|
void StickerSetInner::installDone(const MTPBool &result) {
|
||||||
StickerSets &sets(cRefStickerSets());
|
Stickers::Sets &sets(Global::RefStickerSets());
|
||||||
|
|
||||||
_setFlags &= ~MTPDstickerSet::flag_disabled;
|
_setFlags &= ~MTPDstickerSet::Flag::f_disabled;
|
||||||
sets.insert(_setId, StickerSet(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags)).value().stickers = _pack;
|
auto it = sets.find(_setId);
|
||||||
|
if (it == sets.cend()) {
|
||||||
|
it = sets.insert(_setId, Stickers::Set(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags));
|
||||||
|
}
|
||||||
|
it.value().stickers = _pack;
|
||||||
|
it.value().emoji = _emoji;
|
||||||
|
|
||||||
StickerSetsOrder &order(cRefStickerSetsOrder());
|
Stickers::Order &order(Global::RefStickerSetsOrder());
|
||||||
int32 insertAtIndex = 0, currentIndex = order.indexOf(_setId);
|
int32 insertAtIndex = 0, currentIndex = order.indexOf(_setId);
|
||||||
if (currentIndex != insertAtIndex) {
|
if (currentIndex != insertAtIndex) {
|
||||||
if (currentIndex > 0) {
|
if (currentIndex > 0) {
|
||||||
|
@ -102,7 +136,7 @@ void StickerSetInner::installDone(const MTPBool &result) {
|
||||||
order.insert(insertAtIndex, _setId);
|
order.insert(insertAtIndex, _setId);
|
||||||
}
|
}
|
||||||
|
|
||||||
StickerSets::iterator custom = sets.find(CustomStickerSetId);
|
auto custom = sets.find(Stickers::CustomSetId);
|
||||||
if (custom != sets.cend()) {
|
if (custom != sets.cend()) {
|
||||||
for (int32 i = 0, l = _pack.size(); i < l; ++i) {
|
for (int32 i = 0, l = _pack.size(); i < l; ++i) {
|
||||||
int32 removeIndex = custom->stickers.indexOf(_pack.at(i));
|
int32 removeIndex = custom->stickers.indexOf(_pack.at(i));
|
||||||
|
@ -125,6 +159,47 @@ bool StickerSetInner::installFailed(const RPCError &error) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickerSetInner::mousePressEvent(QMouseEvent *e) {
|
||||||
|
int32 index = stickerFromGlobalPos(e->globalPos());
|
||||||
|
if (index >= 0 && index < _pack.size()) {
|
||||||
|
_previewTimer.start(QApplication::startDragTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerSetInner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
if (_previewShown >= 0) {
|
||||||
|
int32 index = stickerFromGlobalPos(e->globalPos());
|
||||||
|
if (index >= 0 && index < _pack.size() && index != _previewShown) {
|
||||||
|
_previewShown = index;
|
||||||
|
Ui::showStickerPreview(_pack.at(_previewShown));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerSetInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
_previewTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerSetInner::onPreview() {
|
||||||
|
int32 index = stickerFromGlobalPos(QCursor::pos());
|
||||||
|
if (index >= 0 && index < _pack.size()) {
|
||||||
|
_previewShown = index;
|
||||||
|
Ui::showStickerPreview(_pack.at(_previewShown));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 StickerSetInner::stickerFromGlobalPos(const QPoint &p) const {
|
||||||
|
QPoint l(mapFromGlobal(p));
|
||||||
|
if (rtl()) l.setX(width() - l.x());
|
||||||
|
int32 row = (l.y() >= st::stickersPadding.top()) ? qFloor((l.y() - st::stickersPadding.top()) / st::stickersSize.height()) : -1;
|
||||||
|
int32 col = (l.x() >= st::stickersPadding.left()) ? qFloor((l.x() - st::stickersPadding.left()) / st::stickersSize.width()) : -1;
|
||||||
|
if (row >= 0 && col >= 0 && col < StickerPanPerRow) {
|
||||||
|
int32 result = row * StickerPanPerRow + col;
|
||||||
|
return (result < _pack.size()) ? result : -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void StickerSetInner::paintEvent(QPaintEvent *e) {
|
void StickerSetInner::paintEvent(QPaintEvent *e) {
|
||||||
QRect r(e->rect());
|
QRect r(e->rect());
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
@ -149,12 +224,8 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
|
||||||
if (doc->status == FileReady) {
|
if (doc->status == FileReady) {
|
||||||
doc->automaticLoad(0);
|
doc->automaticLoad(0);
|
||||||
}
|
}
|
||||||
if (doc->sticker()->img->isNull() && doc->loaded() && doc->loaded(true)) {
|
if (doc->sticker()->img->isNull() && doc->loaded(DocumentData::FilePathResolveChecked)) {
|
||||||
if (doc->data().isEmpty()) {
|
doc->sticker()->img = doc->data().isEmpty() ? ImagePtr(doc->filepath()) : ImagePtr(doc->data());
|
||||||
doc->sticker()->img = ImagePtr(doc->already());
|
|
||||||
} else {
|
|
||||||
doc->sticker()->img = ImagePtr(doc->data());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,8 +256,8 @@ bool StickerSetInner::loaded() const {
|
||||||
|
|
||||||
int32 StickerSetInner::notInstalled() const {
|
int32 StickerSetInner::notInstalled() const {
|
||||||
if (!_loaded) return 0;
|
if (!_loaded) return 0;
|
||||||
StickerSets::const_iterator it = cStickerSets().constFind(_setId);
|
auto it = Global::StickerSets().constFind(_setId);
|
||||||
if (it == cStickerSets().cend() || (it->flags & MTPDstickerSet::flag_disabled)) return _pack.size();
|
if (it == Global::StickerSets().cend() || (it->flags & MTPDstickerSet::Flag::f_disabled)) return _pack.size();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,14 +682,14 @@ void StickersInner::rebuild() {
|
||||||
int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(qMax(_returnWidth, _removeWidth), _restoreWidth);
|
int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(qMax(_returnWidth, _removeWidth), _restoreWidth);
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
const StickerSetsOrder &order(cStickerSetsOrder());
|
const Stickers::Order &order(Global::StickerSetsOrder());
|
||||||
_animStartTimes.reserve(order.size());
|
_animStartTimes.reserve(order.size());
|
||||||
|
|
||||||
const StickerSets &sets(cStickerSets());
|
const Stickers::Sets &sets(Global::StickerSets());
|
||||||
for (int32 i = 0, l = order.size(); i < l; ++i) {
|
for (int i = 0, l = order.size(); i < l; ++i) {
|
||||||
StickerSets::const_iterator it = sets.constFind(order.at(i));
|
auto it = sets.constFind(order.at(i));
|
||||||
if (it != sets.cend()) {
|
if (it != sets.cend()) {
|
||||||
bool disabled = (it->flags & MTPDstickerSet::flag_disabled);
|
bool disabled = (it->flags & MTPDstickerSet::Flag::f_disabled);
|
||||||
|
|
||||||
DocumentData *sticker = it->stickers.isEmpty() ? 0 : it->stickers.at(0);
|
DocumentData *sticker = it->stickers.isEmpty() ? 0 : it->stickers.at(0);
|
||||||
int32 pixw = 0, pixh = 0;
|
int32 pixw = 0, pixh = 0;
|
||||||
|
@ -643,10 +714,10 @@ void StickersInner::rebuild() {
|
||||||
if (titleWidth > namew) {
|
if (titleWidth > namew) {
|
||||||
title = st::contactsNameFont->elided(title, namew);
|
title = st::contactsNameFont->elided(title, namew);
|
||||||
}
|
}
|
||||||
bool official = (it->flags & MTPDstickerSet::flag_official);
|
bool official = (it->flags & MTPDstickerSet::Flag::f_official);
|
||||||
(disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, official, disabled, pixw, pixh));
|
(disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, official, disabled, pixw, pixh));
|
||||||
_animStartTimes.push_back(0);
|
_animStartTimes.push_back(0);
|
||||||
if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_flag_NOT_LOADED)) {
|
if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
|
||||||
App::api()->scheduleStickerSetRequest(it->id, it->access);
|
App::api()->scheduleStickerSetRequest(it->id, it->access);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -661,8 +732,8 @@ QVector<uint64> StickersInner::getOrder() const {
|
||||||
result.reserve(_rows.size());
|
result.reserve(_rows.size());
|
||||||
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
|
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
|
||||||
if (_rows.at(i)->disabled) {
|
if (_rows.at(i)->disabled) {
|
||||||
StickerSets::const_iterator it = cStickerSets().constFind(_rows.at(i)->id);
|
auto it = Global::StickerSets().constFind(_rows.at(i)->id);
|
||||||
if (it == cStickerSets().cend() || !(it->flags & MTPDstickerSet::flag_official)) {
|
if (it == Global::StickerSets().cend() || !(it->flags & MTPDstickerSet::Flag::f_official)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -704,6 +775,7 @@ StickersBox::StickersBox() : ItemListBox(st::boxScroll)
|
||||||
setMaxHeight(snap(countHeight(), int32(st::sessionsHeight), int32(st::boxMaxListHeight)));
|
setMaxHeight(snap(countHeight(), int32(st::sessionsHeight), int32(st::boxMaxListHeight)));
|
||||||
|
|
||||||
connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated()));
|
connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated()));
|
||||||
|
App::main()->updateStickers();
|
||||||
|
|
||||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||||
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||||
|
@ -761,7 +833,7 @@ void StickersBox::reorderDone(const MTPBool &result) {
|
||||||
bool StickersBox::reorderFail(const RPCError &result) {
|
bool StickersBox::reorderFail(const RPCError &result) {
|
||||||
if (mtpIsFlood(result)) return false;
|
if (mtpIsFlood(result)) return false;
|
||||||
_reorderRequest = 0;
|
_reorderRequest = 0;
|
||||||
cSetLastStickersUpdate(0);
|
Global::SetLastStickersUpdate(0);
|
||||||
App::main()->updateStickers();
|
App::main()->updateStickers();
|
||||||
onClose();
|
onClose();
|
||||||
return true;
|
return true;
|
||||||
|
@ -785,12 +857,12 @@ void StickersBox::closePressed() {
|
||||||
MTP::cancel(i.key());
|
MTP::cancel(i.key());
|
||||||
}
|
}
|
||||||
_disenableRequests.clear();
|
_disenableRequests.clear();
|
||||||
cSetLastStickersUpdate(0);
|
Global::SetLastStickersUpdate(0);
|
||||||
App::main()->updateStickers();
|
App::main()->updateStickers();
|
||||||
} else if (_reorderRequest) {
|
} else if (_reorderRequest) {
|
||||||
MTP::cancel(_reorderRequest);
|
MTP::cancel(_reorderRequest);
|
||||||
_reorderRequest = 0;
|
_reorderRequest = 0;
|
||||||
cSetLastStickersUpdate(0);
|
Global::SetLastStickersUpdate(0);
|
||||||
App::main()->updateStickers();
|
App::main()->updateStickers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -842,11 +914,11 @@ void StickersBox::onSave() {
|
||||||
|
|
||||||
bool writeRecent = false;
|
bool writeRecent = false;
|
||||||
RecentStickerPack &recent(cGetRecentStickers());
|
RecentStickerPack &recent(cGetRecentStickers());
|
||||||
StickerSets &sets(cRefStickerSets());
|
Stickers::Sets &sets(Global::RefStickerSets());
|
||||||
|
|
||||||
QVector<uint64> reorder = _inner.getOrder(), disabled = _inner.getDisabledSets();
|
QVector<uint64> reorder = _inner.getOrder(), disabled = _inner.getDisabledSets();
|
||||||
for (int32 i = 0, l = disabled.size(); i < l; ++i) {
|
for (int32 i = 0, l = disabled.size(); i < l; ++i) {
|
||||||
StickerSets::iterator it = sets.find(disabled.at(i));
|
auto it = sets.find(disabled.at(i));
|
||||||
if (it != sets.cend()) {
|
if (it != sets.cend()) {
|
||||||
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
|
||||||
if (it->stickers.indexOf(i->first) >= 0) {
|
if (it->stickers.indexOf(i->first) >= 0) {
|
||||||
|
@ -856,35 +928,35 @@ void StickersBox::onSave() {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(it->flags & MTPDstickerSet::flag_disabled)) {
|
if (!(it->flags & MTPDstickerSet::Flag::f_disabled)) {
|
||||||
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
|
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
|
||||||
if (it->flags & MTPDstickerSet::flag_official) {
|
if (it->flags & MTPDstickerSet::Flag::f_official) {
|
||||||
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
||||||
it->flags |= MTPDstickerSet::flag_disabled;
|
it->flags |= MTPDstickerSet::Flag::f_disabled;
|
||||||
} else {
|
} else {
|
||||||
_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
||||||
int32 removeIndex = cStickerSetsOrder().indexOf(it->id);
|
int removeIndex = Global::StickerSetsOrder().indexOf(it->id);
|
||||||
if (removeIndex >= 0) cRefStickerSetsOrder().removeAt(removeIndex);
|
if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
|
||||||
sets.erase(it);
|
sets.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StickerSetsOrder &order(cRefStickerSetsOrder());
|
Stickers::Order &order(Global::RefStickerSetsOrder());
|
||||||
order.clear();
|
order.clear();
|
||||||
for (int32 i = 0, l = reorder.size(); i < l; ++i) {
|
for (int i = 0, l = reorder.size(); i < l; ++i) {
|
||||||
StickerSets::iterator it = sets.find(reorder.at(i));
|
auto it = sets.find(reorder.at(i));
|
||||||
if (it != sets.cend()) {
|
if (it != sets.cend()) {
|
||||||
if ((it->flags & MTPDstickerSet::flag_disabled) && !disabled.contains(it->id)) {
|
if ((it->flags & MTPDstickerSet::Flag::f_disabled) && !disabled.contains(it->id)) {
|
||||||
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
|
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
|
||||||
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
|
||||||
it->flags &= ~MTPDstickerSet::flag_disabled;
|
it->flags &= ~MTPDstickerSet::Flag::f_disabled;
|
||||||
}
|
}
|
||||||
order.push_back(reorder.at(i));
|
order.push_back(reorder.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (StickerSets::iterator it = sets.begin(); it != sets.cend();) {
|
for (auto it = sets.begin(); it != sets.cend();) {
|
||||||
if (it->id == CustomStickerSetId || it->id == RecentStickerSetId || order.contains(it->id)) {
|
if (it->id == Stickers::CustomSetId || it->id == Stickers::RecentSetId || order.contains(it->id)) {
|
||||||
++it;
|
++it;
|
||||||
} else {
|
} else {
|
||||||
it = sets.erase(it);
|
it = sets.erase(it);
|
||||||
|
@ -920,12 +992,12 @@ void StickersBox::showAll() {
|
||||||
|
|
||||||
int32 stickerPacksCount(bool includeDisabledOfficial) {
|
int32 stickerPacksCount(bool includeDisabledOfficial) {
|
||||||
int32 result = 0;
|
int32 result = 0;
|
||||||
const StickerSetsOrder &order(cStickerSetsOrder());
|
const Stickers::Order &order(Global::StickerSetsOrder());
|
||||||
const StickerSets &sets(cStickerSets());
|
const Stickers::Sets &sets(Global::StickerSets());
|
||||||
for (int32 i = 0, l = order.size(); i < l; ++i) {
|
for (int i = 0, l = order.size(); i < l; ++i) {
|
||||||
StickerSets::const_iterator it = sets.constFind(order.at(i));
|
auto it = sets.constFind(order.at(i));
|
||||||
if (it != sets.cend()) {
|
if (it != sets.cend()) {
|
||||||
if (!(it->flags & MTPDstickerSet::flag_disabled) || ((it->flags & MTPDstickerSet::flag_official) && includeDisabledOfficial)) {
|
if (!(it->flags & MTPDstickerSet::Flag::f_disabled) || ((it->flags & MTPDstickerSet::Flag::f_official) && includeDisabledOfficial)) {
|
||||||
++result;
|
++result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ public:
|
||||||
|
|
||||||
StickerSetInner(const MTPInputStickerSet &set);
|
StickerSetInner(const MTPInputStickerSet &set);
|
||||||
|
|
||||||
void init();
|
void mousePressEvent(QMouseEvent *e);
|
||||||
|
void mouseMoveEvent(QMouseEvent *e);
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e);
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
|
|
||||||
|
@ -42,10 +44,12 @@ public:
|
||||||
void setScrollBottom(int32 bottom);
|
void setScrollBottom(int32 bottom);
|
||||||
void install();
|
void install();
|
||||||
|
|
||||||
QString getTitle() const;
|
|
||||||
|
|
||||||
~StickerSetInner();
|
~StickerSetInner();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onPreview();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void updateButtons();
|
void updateButtons();
|
||||||
|
@ -53,6 +57,8 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
int32 stickerFromGlobalPos(const QPoint &p) const;
|
||||||
|
|
||||||
void gotSet(const MTPmessages_StickerSet &set);
|
void gotSet(const MTPmessages_StickerSet &set);
|
||||||
bool failedSet(const RPCError &error);
|
bool failedSet(const RPCError &error);
|
||||||
|
|
||||||
|
@ -60,15 +66,20 @@ private:
|
||||||
bool installFailed(const RPCError &error);
|
bool installFailed(const RPCError &error);
|
||||||
|
|
||||||
StickerPack _pack;
|
StickerPack _pack;
|
||||||
|
StickersByEmojiMap _emoji;
|
||||||
bool _loaded;
|
bool _loaded;
|
||||||
uint64 _setId, _setAccess;
|
uint64 _setId, _setAccess;
|
||||||
QString _title, _setTitle, _setShortName;
|
QString _title, _setTitle, _setShortName;
|
||||||
int32 _setCount, _setHash, _setFlags;
|
int32 _setCount, _setHash;
|
||||||
|
MTPDstickerSet::Flags _setFlags;
|
||||||
|
|
||||||
int32 _bottom;
|
int32 _bottom;
|
||||||
MTPInputStickerSet _input;
|
MTPInputStickerSet _input;
|
||||||
|
|
||||||
mtpRequestId _installRequest;
|
mtpRequestId _installRequest;
|
||||||
|
|
||||||
|
QTimer _previewTimer;
|
||||||
|
int32 _previewShown;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StickerSetBox : public ScrollableBox, public RPCSender {
|
class StickerSetBox : public ScrollableBox, public RPCSender {
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
@ -160,7 +160,7 @@ void UsernameBox::onChanged() {
|
||||||
}
|
}
|
||||||
_checkTimer.stop();
|
_checkTimer.stop();
|
||||||
} else {
|
} else {
|
||||||
int32 i, len = name.size();
|
int32 len = name.size();
|
||||||
for (int32 i = 0; i < len; ++i) {
|
for (int32 i = 0; i < len; ++i) {
|
||||||
QChar ch = name.at(i);
|
QChar ch = name.at(i);
|
||||||
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_' && (ch != '@' || i > 0)) {
|
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_' && (ch != '@' || i > 0)) {
|
||||||
|
@ -191,7 +191,7 @@ void UsernameBox::onChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsernameBox::onLinkClick() {
|
void UsernameBox::onLinkClick() {
|
||||||
App::app()->clipboard()->setText(qsl("https://telegram.me/") + getName());
|
Application::clipboard()->setText(qsl("https://telegram.me/") + getName());
|
||||||
_copiedTextLink = lang(lng_username_copied);
|
_copiedTextLink = lang(lng_username_copied);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
3
Telegram/SourceFiles/codegen/style/main.cpp
Normal file
3
Telegram/SourceFiles/codegen/style/main.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -16,14 +16,14 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
static const int32 AppVersion = 9017;
|
static const int32 AppVersion = 9040;
|
||||||
static const wchar_t *AppVersionStr = L"0.9.17";
|
static const wchar_t *AppVersionStr = L"0.9.40";
|
||||||
static const bool DevVersion = false;
|
static const bool DevVersion = false;
|
||||||
//#define BETA_VERSION (9015008ULL) // just comment this line to build public version
|
//#define BETA_VERSION (9034004ULL) // just comment this line to build public version
|
||||||
|
|
||||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||||
static const wchar_t *AppName = L"Telegram Desktop";
|
static const wchar_t *AppName = L"Telegram Desktop";
|
||||||
|
@ -51,11 +51,11 @@ enum {
|
||||||
MTPIPv4ConnectionWaitTimeout = 1000, // 1 seconds waiting for ipv4, until we accept ipv6
|
MTPIPv4ConnectionWaitTimeout = 1000, // 1 seconds waiting for ipv4, until we accept ipv6
|
||||||
MTPMillerRabinIterCount = 30, // 30 Miller-Rabin iterations for dh_prime primality check
|
MTPMillerRabinIterCount = 30, // 30 Miller-Rabin iterations for dh_prime primality check
|
||||||
|
|
||||||
MTPUploadSessionsCount = 4, // max 4 upload sessions is created
|
MTPUploadSessionsCount = 2, // max 2 upload sessions is created
|
||||||
MTPDownloadSessionsCount = 4, // max 4 download sessions is created
|
MTPDownloadSessionsCount = 2, // max 2 download sessions is created
|
||||||
MTPKillFileSessionTimeout = 5000, // how much time without upload / download causes additional session kill
|
MTPKillFileSessionTimeout = 5000, // how much time without upload / download causes additional session kill
|
||||||
|
|
||||||
MTPEnumDCTimeout = 4000, // 4 seconds timeout for help_getConfig to work (them move to other dc)
|
MTPEnumDCTimeout = 8000, // 8 seconds timeout for help_getConfig to work (then move to other dc)
|
||||||
|
|
||||||
MTPDebugBufferSize = 1024 * 1024, // 1 mb start size
|
MTPDebugBufferSize = 1024 * 1024, // 1 mb start size
|
||||||
|
|
||||||
|
@ -101,6 +101,9 @@ enum {
|
||||||
MediaOverviewStartPerPage = 5,
|
MediaOverviewStartPerPage = 5,
|
||||||
MediaOverviewPreloadCount = 4,
|
MediaOverviewPreloadCount = 4,
|
||||||
|
|
||||||
|
// a new message from the same sender is attached to previous within 15 minutes
|
||||||
|
AttachMessageToPreviousSecondsDelta = 900,
|
||||||
|
|
||||||
AudioVoiceMsgSimultaneously = 4,
|
AudioVoiceMsgSimultaneously = 4,
|
||||||
AudioSongSimultaneously = 4,
|
AudioSongSimultaneously = 4,
|
||||||
AudioCheckPositionTimeout = 100, // 100ms per check audio pos
|
AudioCheckPositionTimeout = 100, // 100ms per check audio pos
|
||||||
|
@ -118,6 +121,8 @@ enum {
|
||||||
AudioVoiceMsgInMemory = 2 * 1024 * 1024, // 2 Mb audio is hold in memory and auto loaded
|
AudioVoiceMsgInMemory = 2 * 1024 * 1024, // 2 Mb audio is hold in memory and auto loaded
|
||||||
AudioPauseDeviceTimeout = 3000, // pause in 3 secs after playing is over
|
AudioPauseDeviceTimeout = 3000, // pause in 3 secs after playing is over
|
||||||
|
|
||||||
|
WaveformSamplesCount = 100,
|
||||||
|
|
||||||
StickerInMemory = 2 * 1024 * 1024, // 2 Mb stickers hold in memory, auto loaded and displayed inline
|
StickerInMemory = 2 * 1024 * 1024, // 2 Mb stickers hold in memory, auto loaded and displayed inline
|
||||||
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
||||||
|
|
||||||
|
@ -127,12 +132,13 @@ enum {
|
||||||
MaxZoomLevel = 7, // x8
|
MaxZoomLevel = 7, // x8
|
||||||
ZoomToScreenLevel = 1024, // just constant
|
ZoomToScreenLevel = 1024, // just constant
|
||||||
|
|
||||||
|
ShortcutsCountLimit = 256, // how many shortcuts can be in json file
|
||||||
|
|
||||||
PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request
|
PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request
|
||||||
EmojiPanPerRow = 7,
|
EmojiPanPerRow = 7,
|
||||||
EmojiPanRowsPerPage = 6,
|
EmojiPanRowsPerPage = 6,
|
||||||
StickerPanPerRow = 5,
|
StickerPanPerRow = 5,
|
||||||
StickerPanRowsPerPage = 4,
|
StickerPanRowsPerPage = 4,
|
||||||
SavedGifsMaxPerRow = 4,
|
|
||||||
StickersUpdateTimeout = 3600000, // update not more than once in an hour
|
StickersUpdateTimeout = 3600000, // update not more than once in an hour
|
||||||
|
|
||||||
SearchPeopleLimit = 5,
|
SearchPeopleLimit = 5,
|
||||||
|
@ -140,9 +146,9 @@ enum {
|
||||||
MaxUsernameLength = 32,
|
MaxUsernameLength = 32,
|
||||||
UsernameCheckTimeout = 200,
|
UsernameCheckTimeout = 200,
|
||||||
|
|
||||||
MaxChannelDescription = 120,
|
MaxChannelDescription = 255,
|
||||||
MaxGroupChannelTitle = 255,
|
MaxGroupChannelTitle = 255,
|
||||||
MaxPhotoCaption = 140,
|
MaxPhotoCaption = 200,
|
||||||
|
|
||||||
MaxMessageSize = 4096,
|
MaxMessageSize = 4096,
|
||||||
MaxHttpRedirects = 5, // when getting external data/images
|
MaxHttpRedirects = 5, // when getting external data/images
|
||||||
|
@ -167,6 +173,8 @@ enum {
|
||||||
|
|
||||||
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
|
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
|
||||||
ReloadChannelMembersTimeout = 1000, // 1 second wait before reload members in channel after adding
|
ReloadChannelMembersTimeout = 1000, // 1 second wait before reload members in channel after adding
|
||||||
|
|
||||||
|
PinnedMessageTextLimit = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool isNotificationsUser(uint64 id) {
|
inline bool isNotificationsUser(uint64 id) {
|
||||||
|
@ -191,7 +199,7 @@ inline const char *cGUIDStr() {
|
||||||
return gGuidStr;
|
return gGuidStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char **cPublicRSAKeys(uint32 &cnt) {
|
inline const char **cPublicRSAKeys(int &keysCount) {
|
||||||
static const char *(keys[]) = {"\
|
static const char *(keys[]) = {"\
|
||||||
-----BEGIN RSA PUBLIC KEY-----\n\
|
-----BEGIN RSA PUBLIC KEY-----\n\
|
||||||
MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6\n\
|
MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6\n\
|
||||||
|
@ -201,7 +209,7 @@ Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+\n\
|
||||||
8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n\
|
8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n\
|
||||||
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n\
|
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n\
|
||||||
-----END RSA PUBLIC KEY-----"};
|
-----END RSA PUBLIC KEY-----"};
|
||||||
cnt = sizeof(keys) / sizeof(const char*);
|
keysCount = arraysize(keys);
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -16,10 +16,10 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "style.h"
|
#include "gui/style.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
@ -247,18 +247,15 @@ void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool a
|
||||||
|
|
||||||
History *history = App::history(peer->id);
|
History *history = App::history(peer->id);
|
||||||
|
|
||||||
if (peer->migrateTo()) {
|
PeerData *userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer);
|
||||||
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, peer->migrateTo()->photo->pix(st::dlgPhotoSize));
|
userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth());
|
||||||
} else {
|
|
||||||
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, peer->photo->pix(st::dlgPhotoSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
|
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
|
||||||
int32 namewidth = w - nameleft - st::dlgPaddingHor;
|
int32 namewidth = w - nameleft - st::dlgPaddingHor;
|
||||||
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
|
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
|
||||||
|
|
||||||
// draw chat icon
|
// draw chat icon
|
||||||
if (peer->isChat()) {
|
if (peer->isChat() || peer->isMegagroup()) {
|
||||||
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), App::sprite(), (act ? st::dlgActiveChatImg : st::dlgChatImg));
|
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), App::sprite(), (act ? st::dlgActiveChatImg : st::dlgChatImg));
|
||||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||||
} else if (peer->isChannel()) {
|
} else if (peer->isChannel()) {
|
||||||
|
@ -299,7 +296,7 @@ void DialogsInner::searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) c
|
||||||
p.fillRect(fullRect, st::dlgBG->b);
|
p.fillRect(fullRect, st::dlgBG->b);
|
||||||
if (onlyBackground) return;
|
if (onlyBackground) return;
|
||||||
|
|
||||||
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, _searchInPeer->photo->pix(st::dlgPhotoSize));
|
_searchInPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth());
|
||||||
|
|
||||||
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
|
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
|
||||||
int32 namewidth = w - nameleft - st::dlgPaddingHor * 2 - st::btnCancelSearch.width;
|
int32 namewidth = w - nameleft - st::dlgPaddingHor * 2 - st::btnCancelSearch.width;
|
||||||
|
@ -443,16 +440,12 @@ void DialogsInner::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::createDialog(History *history) {
|
void DialogsInner::createDialog(History *history) {
|
||||||
bool creating = history->dialogs.isEmpty();
|
bool creating = !history->inChatList();
|
||||||
if (creating) {
|
if (creating) {
|
||||||
history->dialogs = dialogs.addToEnd(history);
|
DialogRow *mainRow = history->addToChatList(dialogs);
|
||||||
contactsNoDialogs.del(history->peer, history->dialogs[0]);
|
contactsNoDialogs.del(history->peer, mainRow);
|
||||||
}
|
}
|
||||||
|
RefPair(int32, movedFrom, int32, movedTo) = history->adjustByPosInChatsList(dialogs);
|
||||||
History::DialogLinks links = history->dialogs;
|
|
||||||
int32 movedFrom = links[0]->pos * st::dlgHeight;
|
|
||||||
dialogs.adjustByPos(links);
|
|
||||||
int32 movedTo = links[0]->pos * st::dlgHeight;
|
|
||||||
|
|
||||||
emit dialogMoved(movedFrom, movedTo);
|
emit dialogMoved(movedFrom, movedTo);
|
||||||
|
|
||||||
|
@ -471,8 +464,7 @@ void DialogsInner::removeDialog(History *history) {
|
||||||
if (sel && sel->history == history) {
|
if (sel && sel->history == history) {
|
||||||
sel = 0;
|
sel = 0;
|
||||||
}
|
}
|
||||||
dialogs.del(history->peer);
|
history->removeFromChatList(dialogs);
|
||||||
history->dialogs = History::DialogLinks();
|
|
||||||
history->clearNotifications();
|
history->clearNotifications();
|
||||||
if (App::wnd()) App::wnd()->notifyClear(history);
|
if (App::wnd()) App::wnd()->notifyClear(history);
|
||||||
if (contacts.list.rowByPeer.constFind(history->peer->id) != contacts.list.rowByPeer.cend()) {
|
if (contacts.list.rowByPeer.constFind(history->peer->id) != contacts.list.rowByPeer.cend()) {
|
||||||
|
@ -550,8 +542,8 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (peer) {
|
if (peer) {
|
||||||
if (History *h = App::historyLoaded(peer->id)) {
|
if (History *h = App::historyLoaded(peer->id)) {
|
||||||
if (h->dialogs.contains(0)) {
|
if (h->inChatList()) {
|
||||||
update(0, h->dialogs.value(0)->pos * st::dlgHeight, fullWidth(), st::dlgHeight);
|
update(0, h->posInChatList() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sel) {
|
} else if (sel) {
|
||||||
|
@ -624,7 +616,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
if (_menuPeer->isUser()) {
|
if (_menuPeer->isUser()) {
|
||||||
_menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true);
|
_menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_profile_delete_conversation), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true);
|
_menu->addAction(lang(lng_profile_delete_conversation), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true);
|
||||||
if (_menuPeer->asUser()->access != UserNoAccess) {
|
if (_menuPeer->asUser()->access != UserNoAccess && _menuPeer != App::self()) {
|
||||||
_menu->addAction(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true);
|
_menu->addAction(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true);
|
||||||
connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
||||||
}
|
}
|
||||||
|
@ -651,7 +643,7 @@ void DialogsInner::onContextProfile() {
|
||||||
|
|
||||||
void DialogsInner::onContextToggleNotifications() {
|
void DialogsInner::onContextToggleNotifications() {
|
||||||
if (!_menuPeer) return;
|
if (!_menuPeer) return;
|
||||||
App::main()->updateNotifySetting(_menuPeer, menuPeerMuted());
|
App::main()->updateNotifySetting(_menuPeer, menuPeerMuted() ? NotifySettingSetNotify : NotifySettingSetMuted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::onContextSearch() {
|
void DialogsInner::onContextSearch() {
|
||||||
|
@ -963,7 +955,9 @@ void DialogsInner::dialogsReceived(const QVector<MTPDialog> &added) {
|
||||||
case mtpc_dialog: {
|
case mtpc_dialog: {
|
||||||
const MTPDdialog &d(i->c_dialog());
|
const MTPDdialog &d(i->c_dialog());
|
||||||
history = App::historyFromDialog(peerFromMTP(d.vpeer), d.vunread_count.v, d.vread_inbox_max_id.v);
|
history = App::historyFromDialog(peerFromMTP(d.vpeer), d.vunread_count.v, d.vread_inbox_max_id.v);
|
||||||
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history);
|
if (App::main()) {
|
||||||
|
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_dialogChannel: {
|
case mtpc_dialogChannel: {
|
||||||
|
@ -986,7 +980,9 @@ void DialogsInner::dialogsReceived(const QVector<MTPDialog> &added) {
|
||||||
if (!history->isMegagroup() && d.vtop_message.v > d.vtop_important_message.v) {
|
if (!history->isMegagroup() && d.vtop_message.v > d.vtop_important_message.v) {
|
||||||
history->setNotLoadedAtBottom();
|
history->setNotLoadedAtBottom();
|
||||||
}
|
}
|
||||||
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history);
|
if (App::main()) {
|
||||||
|
App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,7 +1011,7 @@ void DialogsInner::addSavedPeersAfter(const QDateTime &date) {
|
||||||
SavedPeersByTime &saved(cRefSavedPeersByTime());
|
SavedPeersByTime &saved(cRefSavedPeersByTime());
|
||||||
while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) {
|
while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) {
|
||||||
History *history = App::history(saved.last()->id);
|
History *history = App::history(saved.last()->id);
|
||||||
history->setPosInDialogsDate(saved.lastKey());
|
history->setChatsListDate(saved.lastKey());
|
||||||
contactsNoDialogs.del(history->peer);
|
contactsNoDialogs.del(history->peer);
|
||||||
saved.remove(saved.lastKey(), saved.last());
|
saved.remove(saved.lastKey(), saved.last());
|
||||||
}
|
}
|
||||||
|
@ -1040,13 +1036,16 @@ bool DialogsInner::searchReceived(const QVector<MTPMessage> &messages, DialogsSe
|
||||||
_lastSearchDate = lastDateFound;
|
_lastSearchDate = lastDateFound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type == DialogsSearchFromStart || type == DialogsSearchFromOffset) {
|
if (item) {
|
||||||
_lastSearchPeer = item->history()->peer;
|
if (type == DialogsSearchFromStart || type == DialogsSearchFromOffset) {
|
||||||
|
_lastSearchPeer = item->history()->peer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
MsgId msgId = item ? item->id : idFromMessage(*i);
|
||||||
if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
|
if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
|
||||||
_lastSearchMigratedId = item->id;
|
_lastSearchMigratedId = msgId;
|
||||||
} else {
|
} else {
|
||||||
_lastSearchId = item->id;
|
_lastSearchId = msgId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
|
if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
|
||||||
|
@ -1067,8 +1066,11 @@ void DialogsInner::peopleReceived(const QString &query, const QVector<MTPPeer> &
|
||||||
_peopleResults.reserve(people.size());
|
_peopleResults.reserve(people.size());
|
||||||
for (QVector<MTPPeer>::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) {
|
for (QVector<MTPPeer>::const_iterator i = people.cbegin(), e = people.cend(); i != e; ++i) {
|
||||||
PeerId peerId = peerFromMTP(*i);
|
PeerId peerId = peerFromMTP(*i);
|
||||||
History *h = App::historyLoaded(peerId);
|
if (History *h = App::historyLoaded(peerId)) {
|
||||||
if (h && !h->dialogs.isEmpty()) continue; // skip dialogs
|
if (h->inChatList()) {
|
||||||
|
continue; // skip existing chats
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_peopleResults.push_back(App::peer(peerId));
|
_peopleResults.push_back(App::peer(peerId));
|
||||||
}
|
}
|
||||||
|
@ -1359,6 +1361,8 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
|
if (!parentWidget()) return;
|
||||||
|
|
||||||
int32 yTo = yFrom + parentWidget()->height() * 5;
|
int32 yTo = yFrom + parentWidget()->height() * 5;
|
||||||
MTP::clearLoaderPriorities();
|
MTP::clearLoaderPriorities();
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
|
@ -1366,7 +1370,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
if (yFrom < otherStart) {
|
if (yFrom < otherStart) {
|
||||||
dialogs.list.adjustCurrent(yFrom, st::dlgHeight);
|
dialogs.list.adjustCurrent(yFrom, st::dlgHeight);
|
||||||
for (DialogRow *row = dialogs.list.current; row != dialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) {
|
for (DialogRow *row = dialogs.list.current; row != dialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) {
|
||||||
row->history->peer->photo->load();
|
row->history->peer->loadUserpic();
|
||||||
}
|
}
|
||||||
yFrom = 0;
|
yFrom = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1376,7 +1380,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
if (yTo > 0) {
|
if (yTo > 0) {
|
||||||
contactsNoDialogs.list.adjustCurrent(yFrom, st::dlgHeight);
|
contactsNoDialogs.list.adjustCurrent(yFrom, st::dlgHeight);
|
||||||
for (DialogRow *row = contactsNoDialogs.list.current; row != contactsNoDialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) {
|
for (DialogRow *row = contactsNoDialogs.list.current; row != contactsNoDialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) {
|
||||||
row->history->peer->photo->load();
|
row->history->peer->loadUserpic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
|
@ -1387,7 +1391,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
if (to > _filterResults.size()) to = _filterResults.size();
|
if (to > _filterResults.size()) to = _filterResults.size();
|
||||||
|
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
_filterResults[from]->history->peer->photo->load();
|
_filterResults[from]->history->peer->loadUserpic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1398,7 +1402,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
if (to > _peopleResults.size()) to = _peopleResults.size();
|
if (to > _peopleResults.size()) to = _peopleResults.size();
|
||||||
|
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
_peopleResults[from]->photo->load();
|
_peopleResults[from]->loadUserpic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
from = (yFrom > filteredOffset() + ((_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size() - _peopleResults.size();
|
from = (yFrom > filteredOffset() + ((_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size() - _peopleResults.size();
|
||||||
|
@ -1408,7 +1412,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
||||||
if (to > _searchResults.size()) to = _searchResults.size();
|
if (to > _searchResults.size()) to = _searchResults.size();
|
||||||
|
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
_searchResults[from]->_item->history()->peer->photo->load();
|
_searchResults[from]->_item->history()->peer->loadUserpic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1515,6 +1519,11 @@ void DialogsInner::destroyData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||||
|
if (!inPeer) {
|
||||||
|
outPeer = 0;
|
||||||
|
outMsg = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id);
|
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id);
|
||||||
if (i == dialogs.list.rowByPeer.constEnd()) {
|
if (i == dialogs.list.rowByPeer.constEnd()) {
|
||||||
|
@ -1599,6 +1608,11 @@ void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&ou
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
void DialogsInner::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||||
|
if (!inPeer) {
|
||||||
|
outPeer = 0;
|
||||||
|
outMsg = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id);
|
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id);
|
||||||
if (i == dialogs.list.rowByPeer.constEnd()) {
|
if (i == dialogs.list.rowByPeer.constEnd()) {
|
||||||
|
@ -1777,11 +1791,11 @@ void DialogsWidget::activate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::createDialog(History *history) {
|
void DialogsWidget::createDialog(History *history) {
|
||||||
bool creating = history->dialogs.isEmpty();
|
bool creating = !history->inChatList();
|
||||||
_inner.createDialog(history);
|
_inner.createDialog(history);
|
||||||
if (creating && history->peer->migrateFrom()) {
|
if (creating && history->peer->migrateFrom()) {
|
||||||
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
|
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
|
||||||
if (!h->dialogs.isEmpty()) {
|
if (h->inChatList()) {
|
||||||
removeDialog(h);
|
removeDialog(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2038,8 +2052,11 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
||||||
MTP::cancel(_searchRequest);
|
MTP::cancel(_searchRequest);
|
||||||
}
|
}
|
||||||
if (_searchInPeer) {
|
if (_searchInPeer) {
|
||||||
int32 flags = (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
|
MTPmessages_Search::Flags flags = 0;
|
||||||
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchPeerFromStart));
|
if (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) {
|
||||||
|
flags |= MTPmessages_Search::Flag::f_important_only;
|
||||||
|
}
|
||||||
|
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchPeerFromStart));
|
||||||
} else {
|
} else {
|
||||||
_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(0), MTP_inputPeerEmpty(), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchFromStart));
|
_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(0), MTP_inputPeerEmpty(), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, DialogsSearchFromStart));
|
||||||
}
|
}
|
||||||
|
@ -2077,6 +2094,7 @@ void DialogsWidget::onChooseByDrag() {
|
||||||
void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
||||||
if ((_filter.getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
if ((_filter.getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
||||||
if (inPeer) {
|
if (inPeer) {
|
||||||
|
onCancelSearch();
|
||||||
_searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer;
|
_searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer;
|
||||||
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0;
|
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0;
|
||||||
_inner.searchInPeer(_searchInPeer);
|
_inner.searchInPeer(_searchInPeer);
|
||||||
|
@ -2098,8 +2116,11 @@ void DialogsWidget::onSearchMore() {
|
||||||
PeerData *offsetPeer = _inner.lastSearchPeer();
|
PeerData *offsetPeer = _inner.lastSearchPeer();
|
||||||
MsgId offsetId = _inner.lastSearchId();
|
MsgId offsetId = _inner.lastSearchId();
|
||||||
if (_searchInPeer) {
|
if (_searchInPeer) {
|
||||||
int32 flags = (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
|
MTPmessages_Search::Flags flags = 0;
|
||||||
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart));
|
if (_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) {
|
||||||
|
flags |= MTPmessages_Search::Flag::f_important_only;
|
||||||
|
}
|
||||||
|
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart));
|
||||||
} else {
|
} else {
|
||||||
_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(offsetDate), offsetPeer ? offsetPeer->input : MTP_inputPeerEmpty(), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart));
|
_searchRequest = MTP::send(MTPmessages_SearchGlobal(MTP_string(_searchQuery), MTP_int(offsetDate), offsetPeer ? offsetPeer->input : MTP_inputPeerEmpty(), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchFromOffset : DialogsSearchFromStart));
|
||||||
}
|
}
|
||||||
|
@ -2108,8 +2129,11 @@ void DialogsWidget::onSearchMore() {
|
||||||
}
|
}
|
||||||
} else if (_searchInMigrated && !_searchFullMigrated) {
|
} else if (_searchInMigrated && !_searchFullMigrated) {
|
||||||
MsgId offsetMigratedId = _inner.lastSearchMigratedId();
|
MsgId offsetMigratedId = _inner.lastSearchMigratedId();
|
||||||
int32 flags = (_searchInMigrated->isChannel() && !_searchInMigrated->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0;
|
MTPmessages_Search::Flags flags = 0;
|
||||||
_searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _searchInMigrated->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetMigratedId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart), rpcFail(&DialogsWidget::searchFailed, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart));
|
if (_searchInMigrated->isChannel() && !_searchInMigrated->isMegagroup()) {
|
||||||
|
flags |= MTPmessages_Search::Flag::f_important_only;
|
||||||
|
}
|
||||||
|
_searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInMigrated->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetMigratedId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart), rpcFail(&DialogsWidget::searchFailed, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2268,7 +2292,7 @@ void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) {
|
||||||
_dragForward = e->mimeData()->hasFormat(qsl("application/x-td-forward-selected"));
|
_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-link"));
|
||||||
if (!_dragForward) _dragForward = e->mimeData()->hasFormat(qsl("application/x-td-forward-pressed"));
|
if (!_dragForward) _dragForward = e->mimeData()->hasFormat(qsl("application/x-td-forward-pressed"));
|
||||||
if (_dragForward && !cWideMode()) _dragForward = false;
|
if (_dragForward && Adaptive::OneColumn()) _dragForward = false;
|
||||||
if (_dragForward) {
|
if (_dragForward) {
|
||||||
e->setDropAction(Qt::CopyAction);
|
e->setDropAction(Qt::CopyAction);
|
||||||
e->accept();
|
e->accept();
|
||||||
|
@ -2540,7 +2564,7 @@ bool DialogsWidget::onCancelSearch() {
|
||||||
_searchRequest = 0;
|
_searchRequest = 0;
|
||||||
}
|
}
|
||||||
if (_searchInPeer && !clearing) {
|
if (_searchInPeer && !clearing) {
|
||||||
if (!cWideMode()) {
|
if (Adaptive::OneColumn()) {
|
||||||
Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId);
|
Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId);
|
||||||
}
|
}
|
||||||
_searchInPeer = _searchInMigrated = 0;
|
_searchInPeer = _searchInMigrated = 0;
|
||||||
|
@ -2560,7 +2584,7 @@ void DialogsWidget::onCancelSearchInPeer() {
|
||||||
_searchRequest = 0;
|
_searchRequest = 0;
|
||||||
}
|
}
|
||||||
if (_searchInPeer) {
|
if (_searchInPeer) {
|
||||||
if (!cWideMode() && !App::main()->selectingPeer()) {
|
if (Adaptive::OneColumn() && !App::main()->selectingPeer()) {
|
||||||
Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId);
|
Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId);
|
||||||
}
|
}
|
||||||
_searchInPeer = _searchInMigrated = 0;
|
_searchInPeer = _searchInMigrated = 0;
|
||||||
|
@ -2570,7 +2594,7 @@ void DialogsWidget::onCancelSearchInPeer() {
|
||||||
_filter.clear();
|
_filter.clear();
|
||||||
_filter.updatePlaceholder();
|
_filter.updatePlaceholder();
|
||||||
onFilterUpdate();
|
onFilterUpdate();
|
||||||
if (cWideMode() && !App::main()->selectingPeer()) {
|
if (!Adaptive::OneColumn() && !App::main()->selectingPeer()) {
|
||||||
emit cancelled();
|
emit cancelled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -67,7 +67,6 @@ public:
|
||||||
void selectSkipPage(int32 pixels, int32 direction);
|
void selectSkipPage(int32 pixels, int32 direction);
|
||||||
|
|
||||||
void createDialog(History *history);
|
void createDialog(History *history);
|
||||||
void moveDialogToTop(const History::DialogLinks &links);
|
|
||||||
void dlgUpdated(DialogRow *row);
|
void dlgUpdated(DialogRow *row);
|
||||||
void dlgUpdated(History *row, MsgId msgId);
|
void dlgUpdated(History *row, MsgId msgId);
|
||||||
void removeDialog(History *history);
|
void removeDialog(History *history);
|
||||||
|
@ -220,15 +219,15 @@ public:
|
||||||
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
|
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
|
||||||
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
|
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *e);
|
void dragEnterEvent(QDragEnterEvent *e) override;
|
||||||
void dragMoveEvent(QDragMoveEvent *e);
|
void dragMoveEvent(QDragMoveEvent *e) override;
|
||||||
void dragLeaveEvent(QDragLeaveEvent *e);
|
void dragLeaveEvent(QDragLeaveEvent *e) override;
|
||||||
void dropEvent(QDropEvent *e);
|
void dropEvent(QDropEvent *e) override;
|
||||||
void updateDragInScroll(bool inScroll);
|
void updateDragInScroll(bool inScroll);
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void keyPressEvent(QKeyEvent *e);
|
void keyPressEvent(QKeyEvent *e) override;
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void searchInPeer(PeerData *peer);
|
void searchInPeer(PeerData *peer);
|
||||||
|
|
||||||
|
@ -260,6 +259,11 @@ public:
|
||||||
|
|
||||||
void updateNotifySettings(PeerData *peer);
|
void updateNotifySettings(PeerData *peer);
|
||||||
|
|
||||||
|
void rpcClear() override {
|
||||||
|
_inner.rpcClear();
|
||||||
|
RPCSender::rpcClear();
|
||||||
|
}
|
||||||
|
|
||||||
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -157,8 +157,21 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmojiPanel;
|
namespace InlineBots {
|
||||||
static const int EmojiColorsCount = 5;
|
namespace Layout {
|
||||||
|
class ItemBase;
|
||||||
|
} // namespace Layout
|
||||||
|
class Result;
|
||||||
|
} // namespace InlineBots
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
constexpr int InlineItemsMaxPerRow = 5;
|
||||||
|
constexpr int EmojiColorsCount = 5;
|
||||||
|
|
||||||
|
using InlineResult = InlineBots::Result;
|
||||||
|
using InlineResults = QList<InlineBots::Result*>;
|
||||||
|
using InlineItem = InlineBots::Layout::ItemBase;
|
||||||
|
|
||||||
class EmojiColorPicker : public TWidget {
|
class EmojiColorPicker : public TWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -222,6 +235,7 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EmojiPanel;
|
||||||
class EmojiPanInner : public TWidget {
|
class EmojiPanInner : public TWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -359,8 +373,8 @@ public:
|
||||||
|
|
||||||
uint64 currentSet(int yOffset) const;
|
uint64 currentSet(int yOffset) const;
|
||||||
|
|
||||||
void ui_repaintInlineItem(const LayoutInlineItem *layout);
|
void ui_repaintInlineItem(const InlineItem *layout);
|
||||||
bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
|
bool ui_isInlineItemVisible(const InlineItem *layout);
|
||||||
bool ui_isInlineItemBeingChosen();
|
bool ui_isInlineItemBeingChosen();
|
||||||
|
|
||||||
bool inlineResultsShown() const {
|
bool inlineResultsShown() const {
|
||||||
|
@ -368,11 +382,7 @@ public:
|
||||||
}
|
}
|
||||||
int32 countHeight(bool plain = false);
|
int32 countHeight(bool plain = false);
|
||||||
|
|
||||||
~StickerPanInner() {
|
~StickerPanInner();
|
||||||
clearInlineRows(true);
|
|
||||||
deleteUnusedGifLayouts();
|
|
||||||
deleteUnusedInlineLayouts();
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -385,7 +395,7 @@ signals:
|
||||||
|
|
||||||
void selected(DocumentData *sticker);
|
void selected(DocumentData *sticker);
|
||||||
void selected(PhotoData *photo);
|
void selected(PhotoData *photo);
|
||||||
void selected(InlineResult *result, UserData *bot);
|
void selected(InlineBots::Result *result, UserData *bot);
|
||||||
|
|
||||||
void removing(quint64 setId);
|
void removing(quint64 setId);
|
||||||
|
|
||||||
|
@ -420,10 +430,10 @@ private:
|
||||||
int32 _top;
|
int32 _top;
|
||||||
|
|
||||||
struct DisplayedSet {
|
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) {
|
DisplayedSet(uint64 id, MTPDstickerSet::Flags flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), hovers(hoversSize, 0), pack(pack) {
|
||||||
}
|
}
|
||||||
uint64 id;
|
uint64 id;
|
||||||
int32 flags;
|
MTPDstickerSet::Flags flags;
|
||||||
QString title;
|
QString title;
|
||||||
QVector<float64> hovers;
|
QVector<float64> hovers;
|
||||||
StickerPack pack;
|
StickerPack pack;
|
||||||
|
@ -439,7 +449,7 @@ private:
|
||||||
QTimer _updateInlineItems;
|
QTimer _updateInlineItems;
|
||||||
bool _inlineWithThumb;
|
bool _inlineWithThumb;
|
||||||
|
|
||||||
typedef QVector<LayoutInlineItem*> InlineItems;
|
typedef QVector<InlineItem*> InlineItems;
|
||||||
struct InlineRow {
|
struct InlineRow {
|
||||||
InlineRow() : height(0) {
|
InlineRow() : height(0) {
|
||||||
}
|
}
|
||||||
|
@ -450,13 +460,13 @@ private:
|
||||||
InlineRows _inlineRows;
|
InlineRows _inlineRows;
|
||||||
void clearInlineRows(bool resultsDeleted);
|
void clearInlineRows(bool resultsDeleted);
|
||||||
|
|
||||||
typedef QMap<DocumentData*, LayoutInlineGif*> GifLayouts;
|
using GifLayouts = QMap<DocumentData*, InlineItem*>;
|
||||||
GifLayouts _gifLayouts;
|
GifLayouts _gifLayouts;
|
||||||
LayoutInlineGif *layoutPrepareSavedGif(DocumentData *doc, int32 position);
|
InlineItem *layoutPrepareSavedGif(DocumentData *doc, int32 position);
|
||||||
|
|
||||||
typedef QMap<InlineResult*, LayoutInlineItem*> InlineLayouts;
|
using InlineLayouts = QMap<InlineResult*, InlineItem*>;
|
||||||
InlineLayouts _inlineLayouts;
|
InlineLayouts _inlineLayouts;
|
||||||
LayoutInlineItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
|
InlineItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
|
||||||
|
|
||||||
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth);
|
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth);
|
||||||
bool inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force = false);
|
bool inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force = false);
|
||||||
|
@ -469,7 +479,6 @@ private:
|
||||||
int32 validateExistingInlineRows(const InlineResults &results);
|
int32 validateExistingInlineRows(const InlineResults &results);
|
||||||
int32 _selected, _pressedSel;
|
int32 _selected, _pressedSel;
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
TextLinkPtr _linkOver, _linkDown;
|
|
||||||
|
|
||||||
LinkButton _settings;
|
LinkButton _settings;
|
||||||
|
|
||||||
|
@ -482,7 +491,7 @@ class EmojiPanel : public TWidget {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool special, int32 wantedY); // NoneStickerSetId if in emoji
|
EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool special, int32 wantedY); // Stickers::NoneSetId if in emoji
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
void setDeleteVisible(bool isVisible);
|
void setDeleteVisible(bool isVisible);
|
||||||
|
|
||||||
|
@ -532,6 +541,8 @@ protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
class EmojiPan : public TWidget, public RPCSender {
|
class EmojiPan : public TWidget, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -580,8 +591,8 @@ public:
|
||||||
).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
|
).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_repaintInlineItem(const LayoutInlineItem *layout);
|
void ui_repaintInlineItem(const InlineBots::Layout::ItemBase *layout);
|
||||||
bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
|
bool ui_isInlineItemVisible(const InlineBots::Layout::ItemBase *layout);
|
||||||
bool ui_isInlineItemBeingChosen();
|
bool ui_isInlineItemBeingChosen();
|
||||||
|
|
||||||
bool inlineResultsShown() const {
|
bool inlineResultsShown() const {
|
||||||
|
@ -622,7 +633,7 @@ signals:
|
||||||
void emojiSelected(EmojiPtr emoji);
|
void emojiSelected(EmojiPtr emoji);
|
||||||
void stickerSelected(DocumentData *sticker);
|
void stickerSelected(DocumentData *sticker);
|
||||||
void photoSelected(PhotoData *photo);
|
void photoSelected(PhotoData *photo);
|
||||||
void inlineResultSelected(InlineResult *result, UserData *bot);
|
void inlineResultSelected(InlineBots::Result *result, UserData *bot);
|
||||||
|
|
||||||
void updateStickers();
|
void updateStickers();
|
||||||
|
|
||||||
|
@ -642,7 +653,7 @@ private:
|
||||||
void updateIcons();
|
void updateIcons();
|
||||||
|
|
||||||
void prepareTab(int32 &left, int32 top, int32 _width, FlatRadiobutton &tab);
|
void prepareTab(int32 &left, int32 top, int32 _width, FlatRadiobutton &tab);
|
||||||
void updatePanelsPositions(const QVector<EmojiPanel*> &panels, int32 st);
|
void updatePanelsPositions(const QVector<internal::EmojiPanel*> &panels, int32 st);
|
||||||
|
|
||||||
void showAll();
|
void showAll();
|
||||||
void hideAll();
|
void hideAll();
|
||||||
|
@ -661,7 +672,7 @@ private:
|
||||||
BoxShadow _shadow;
|
BoxShadow _shadow;
|
||||||
|
|
||||||
FlatRadiobutton _recent, _people, _nature, _food, _activity, _travel, _objects, _symbols;
|
FlatRadiobutton _recent, _people, _nature, _food, _activity, _travel, _objects, _symbols;
|
||||||
QList<StickerIcon> _icons;
|
QList<internal::StickerIcon> _icons;
|
||||||
QVector<float64> _iconHovers;
|
QVector<float64> _iconHovers;
|
||||||
int32 _iconOver, _iconSel, _iconDown;
|
int32 _iconOver, _iconSel, _iconDown;
|
||||||
bool _iconsDragging;
|
bool _iconsDragging;
|
||||||
|
@ -681,13 +692,13 @@ private:
|
||||||
Animation _a_slide;
|
Animation _a_slide;
|
||||||
|
|
||||||
ScrollArea e_scroll;
|
ScrollArea e_scroll;
|
||||||
EmojiPanInner e_inner;
|
internal::EmojiPanInner e_inner;
|
||||||
QVector<EmojiPanel*> e_panels;
|
QVector<internal::EmojiPanel*> e_panels;
|
||||||
EmojiSwitchButton e_switch;
|
internal::EmojiSwitchButton e_switch;
|
||||||
ScrollArea s_scroll;
|
ScrollArea s_scroll;
|
||||||
StickerPanInner s_inner;
|
internal::StickerPanInner s_inner;
|
||||||
QVector<EmojiPanel*> s_panels;
|
QVector<internal::EmojiPanel*> s_panels;
|
||||||
EmojiSwitchButton s_switch;
|
internal::EmojiSwitchButton s_switch;
|
||||||
|
|
||||||
uint64 _removingSetId;
|
uint64 _removingSetId;
|
||||||
|
|
||||||
|
@ -699,13 +710,9 @@ private:
|
||||||
clearResults();
|
clearResults();
|
||||||
}
|
}
|
||||||
QString nextOffset;
|
QString nextOffset;
|
||||||
InlineResults results;
|
QString switchPmText, switchPmStartParam;
|
||||||
void clearResults() {
|
internal::InlineResults results;
|
||||||
for (int32 i = 0, l = results.size(); i < l; ++i) {
|
void clearResults();
|
||||||
delete results.at(i);
|
|
||||||
}
|
|
||||||
results.clear();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
typedef QMap<QString, InlineCacheEntry*> InlineCache;
|
typedef QMap<QString, InlineCacheEntry*> InlineCache;
|
||||||
InlineCache _inlineCache;
|
InlineCache _inlineCache;
|
||||||
|
@ -734,18 +741,20 @@ class MentionsInner : public TWidget {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MentionsInner(MentionsDropdown *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows);
|
MentionsInner(MentionsDropdown *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows, StickerPack *srows);
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
void enterEvent(QEvent *e);
|
void enterEvent(QEvent *e);
|
||||||
void leaveEvent(QEvent *e);
|
void leaveEvent(QEvent *e);
|
||||||
|
|
||||||
void mousePressEvent(QMouseEvent *e);
|
void mousePressEvent(QMouseEvent *e);
|
||||||
void mouseMoveEvent(QMouseEvent *e);
|
void mouseMoveEvent(QMouseEvent *e);
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e);
|
||||||
|
|
||||||
void clearSel();
|
void clearSel(bool hidden = false);
|
||||||
bool moveSel(int direction);
|
bool moveSel(int key);
|
||||||
bool select();
|
bool select();
|
||||||
|
|
||||||
void setRecentInlineBotsInRows(int32 bots);
|
void setRecentInlineBotsInRows(int32 bots);
|
||||||
|
@ -755,27 +764,35 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void chosen(QString mentionOrHashtag);
|
void chosen(QString mentionOrHashtag);
|
||||||
|
void selected(DocumentData *sticker);
|
||||||
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onParentGeometryChanged();
|
void onParentGeometryChanged();
|
||||||
void onUpdateSelected(bool force = false);
|
void onUpdateSelected(bool force = false);
|
||||||
|
void onPreview();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void updateSelectedRow();
|
||||||
void setSel(int sel, bool scroll = false);
|
void setSel(int sel, bool scroll = false);
|
||||||
|
|
||||||
MentionsDropdown *_parent;
|
MentionsDropdown *_parent;
|
||||||
MentionRows *_mrows;
|
MentionRows *_mrows;
|
||||||
HashtagRows *_hrows;
|
HashtagRows *_hrows;
|
||||||
BotCommandRows *_brows;
|
BotCommandRows *_brows;
|
||||||
int32 _recentInlineBotsInRows;
|
StickerPack *_srows;
|
||||||
int32 _sel;
|
int32 _stickersPerRow, _recentInlineBotsInRows;
|
||||||
|
int32 _sel, _down;
|
||||||
bool _mouseSel;
|
bool _mouseSel;
|
||||||
QPoint _mousePos;
|
QPoint _mousePos;
|
||||||
|
|
||||||
bool _overDelete;
|
bool _overDelete;
|
||||||
|
|
||||||
|
bool _previewShown;
|
||||||
|
|
||||||
|
QTimer _previewTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MentionsDropdown : public TWidget {
|
class MentionsDropdown : public TWidget {
|
||||||
|
@ -791,7 +808,8 @@ public:
|
||||||
|
|
||||||
bool clearFilteredBotCommands();
|
bool clearFilteredBotCommands();
|
||||||
void showFiltered(PeerData *peer, QString query, bool start);
|
void showFiltered(PeerData *peer, QString query, bool start);
|
||||||
void updateFiltered(bool toDown = false);
|
void showStickers(EmojiPtr emoji);
|
||||||
|
void updateFiltered(bool resetScroll = false);
|
||||||
void setBoundings(QRect boundings);
|
void setBoundings(QRect boundings);
|
||||||
|
|
||||||
void step_appearance(float64 ms, bool timer);
|
void step_appearance(float64 ms, bool timer);
|
||||||
|
@ -807,6 +825,10 @@ public:
|
||||||
bool eventFilter(QObject *obj, QEvent *e);
|
bool eventFilter(QObject *obj, QEvent *e);
|
||||||
QString getSelected() const;
|
QString getSelected() const;
|
||||||
|
|
||||||
|
bool stickersShown() const {
|
||||||
|
return !_srows.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
bool overlaps(const QRect &globalRect) {
|
bool overlaps(const QRect &globalRect) {
|
||||||
if (isHidden() || !testAttribute(Qt::WA_OpaquePaintEvent)) return false;
|
if (isHidden() || !testAttribute(Qt::WA_OpaquePaintEvent)) return false;
|
||||||
|
|
||||||
|
@ -818,6 +840,7 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void chosen(QString mentionOrHashtag);
|
void chosen(QString mentionOrHashtag);
|
||||||
|
void stickerSelected(DocumentData *sticker);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -828,14 +851,15 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void recount(bool toDown = false);
|
void recount(bool resetScroll = false);
|
||||||
|
|
||||||
QPixmap _cache;
|
QPixmap _cache;
|
||||||
MentionRows _mrows;
|
MentionRows _mrows;
|
||||||
HashtagRows _hrows;
|
HashtagRows _hrows;
|
||||||
BotCommandRows _brows;
|
BotCommandRows _brows;
|
||||||
|
StickerPack _srows;
|
||||||
|
|
||||||
void rowsUpdated(const MentionRows &mrows, const HashtagRows &hrows, const BotCommandRows &brows, bool toDown);
|
void rowsUpdated(const MentionRows &mrows, const HashtagRows &hrows, const BotCommandRows &brows, const StickerPack &srows, bool resetScroll);
|
||||||
|
|
||||||
ScrollArea _scroll;
|
ScrollArea _scroll;
|
||||||
MentionsInner _inner;
|
MentionsInner _inner;
|
||||||
|
@ -843,6 +867,7 @@ private:
|
||||||
ChatData *_chat;
|
ChatData *_chat;
|
||||||
UserData *_user;
|
UserData *_user;
|
||||||
ChannelData *_channel;
|
ChannelData *_channel;
|
||||||
|
EmojiPtr _emoji;
|
||||||
QString _filter;
|
QString _filter;
|
||||||
QRect _boundings;
|
QRect _boundings;
|
||||||
bool _addInlineBots;
|
bool _addInlineBots;
|
||||||
|
|
|
@ -16,19 +16,26 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
|
#include "boxes/confirmbox.h"
|
||||||
|
|
||||||
#include "layerwidget.h"
|
#include "layerwidget.h"
|
||||||
|
#include "lang.h"
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ClickHandlerPtr);
|
||||||
|
Q_DECLARE_METATYPE(Qt::MouseButton);
|
||||||
|
|
||||||
namespace App {
|
namespace App {
|
||||||
|
|
||||||
void sendBotCommand(const QString &cmd, MsgId replyTo) {
|
void sendBotCommand(PeerData *peer, const QString &cmd, MsgId replyTo) {
|
||||||
if (MainWidget *m = main()) m->sendBotCommand(cmd, replyTo);
|
if (MainWidget *m = main()) m->sendBotCommand(peer, cmd, replyTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insertBotCommand(const QString &cmd, bool specialGif) {
|
bool insertBotCommand(const QString &cmd, bool specialGif) {
|
||||||
|
@ -36,12 +43,55 @@ namespace App {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
void activateBotCommand(const HistoryItem *msg, int row, int col) {
|
||||||
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0);
|
const HistoryMessageReplyMarkup::Button *button = nullptr;
|
||||||
|
if (auto *markup = msg->Get<HistoryMessageReplyMarkup>()) {
|
||||||
|
if (row < markup->rows.size()) {
|
||||||
|
const HistoryMessageReplyMarkup::ButtonRow &buttonRow(markup->rows.at(row));
|
||||||
|
if (col < buttonRow.size()) {
|
||||||
|
button = &buttonRow.at(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!button) return;
|
||||||
|
|
||||||
|
switch (button->type) {
|
||||||
|
case HistoryMessageReplyMarkup::Button::Default: {
|
||||||
|
// Copy string before passing it to the sending method
|
||||||
|
// because the original button can be destroyed inside.
|
||||||
|
MsgId replyTo = (msg->id > 0) ? msg->id : 0;
|
||||||
|
sendBotCommand(msg->history()->peer, QString(button->text), replyTo);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HistoryMessageReplyMarkup::Button::Callback: {
|
||||||
|
if (MainWidget *m = main()) {
|
||||||
|
m->app_sendBotCallback(button, msg, row, col);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HistoryMessageReplyMarkup::Button::Url: {
|
||||||
|
auto url = QString::fromUtf8(button->data);
|
||||||
|
HiddenUrlClickHandler(url).onClick(Qt::LeftButton);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HistoryMessageReplyMarkup::Button::RequestLocation: {
|
||||||
|
Ui::showLayer(new InformBox(lang(lng_bot_share_location_unavailable)));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HistoryMessageReplyMarkup::Button::RequestPhone: {
|
||||||
|
SharePhoneConfirmBox *box = new SharePhoneConfirmBox(msg->history()->peer);
|
||||||
|
box->connect(box, SIGNAL(confirmed(PeerData*)), App::main(), SLOT(onSharePhoneWithBot(PeerData*)));
|
||||||
|
Ui::showLayer(box);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void openPeerByName(const QString &username, bool toProfile, const QString &startToken) {
|
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
||||||
if (MainWidget *m = main()) m->openPeerByName(username, toProfile, startToken);
|
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel() && !inPeer->isMegagroup()) ? inPeer : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openPeerByName(const QString &username, MsgId msgId, const QString &startToken) {
|
||||||
|
if (MainWidget *m = main()) m->openPeerByName(username, msgId, startToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
void joinGroupByHash(const QString &hash) {
|
void joinGroupByHash(const QString &hash) {
|
||||||
|
@ -62,11 +112,29 @@ namespace App {
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeDialog(History *history) {
|
void removeDialog(History *history) {
|
||||||
if (MainWidget *m = main()) m->removeDialog(history);
|
if (MainWidget *m = main()) {
|
||||||
|
m->removeDialog(history);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showSettings() {
|
void showSettings() {
|
||||||
if (Window *win = wnd()) win->showSettings();
|
if (Window *w = wnd()) {
|
||||||
|
w->showSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) {
|
||||||
|
if (Window *w = wnd()) {
|
||||||
|
qRegisterMetaType<ClickHandlerPtr>();
|
||||||
|
qRegisterMetaType<Qt::MouseButton>();
|
||||||
|
QMetaObject::invokeMethod(w, "app_activateClickHandler", Qt::QueuedConnection, Q_ARG(ClickHandlerPtr, handler), Q_ARG(Qt::MouseButton, button));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void logOutDelayed() {
|
||||||
|
if (Window *w = App::wnd()) {
|
||||||
|
QMetaObject::invokeMethod(w, "onLogoutSure", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,11 +142,15 @@ namespace App {
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
void showStickerPreview(DocumentData *sticker) {
|
void showStickerPreview(DocumentData *sticker) {
|
||||||
if (MainWidget *m = App::main()) m->ui_showStickerPreview(sticker);
|
if (Window *w = App::wnd()) {
|
||||||
|
w->ui_showStickerPreview(sticker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideStickerPreview() {
|
void hideStickerPreview() {
|
||||||
if (MainWidget *m = App::main()) m->ui_hideStickerPreview();
|
if (Window *w = App::wnd()) {
|
||||||
|
w->ui_hideStickerPreview();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showLayer(LayeredWidget *box, ShowLayerOptions options) {
|
void showLayer(LayeredWidget *box, ShowLayerOptions options) {
|
||||||
|
@ -113,16 +185,22 @@ namespace Ui {
|
||||||
if (MainWidget *m = App::main()) m->ui_repaintHistoryItem(item);
|
if (MainWidget *m = App::main()) m->ui_repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void repaintInlineItem(const LayoutInlineItem *layout) {
|
void repaintInlineItem(const InlineBots::Layout::ItemBase *layout) {
|
||||||
if (!layout) return;
|
if (!layout) return;
|
||||||
if (MainWidget *m = App::main()) m->ui_repaintInlineItem(layout);
|
if (MainWidget *m = App::main()) m->ui_repaintInlineItem(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInlineItemVisible(const LayoutInlineItem *layout) {
|
bool isInlineItemVisible(const InlineBots::Layout::ItemBase *layout) {
|
||||||
if (MainWidget *m = App::main()) return m->ui_isInlineItemVisible(layout);
|
if (MainWidget *m = App::main()) return m->ui_isInlineItemVisible(layout);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void autoplayMediaInlineAsync(const FullMsgId &msgId) {
|
||||||
|
if (MainWidget *m = App::main()) {
|
||||||
|
QMetaObject::invokeMethod(m, "ui_autoplayMediaInlineAsync", Qt::QueuedConnection, Q_ARG(qint32, msgId.channel), Q_ARG(qint32, msgId.msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back) {
|
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back) {
|
||||||
if (MainWidget *m = App::main()) m->ui_showPeerHistory(peer, msgId, back);
|
if (MainWidget *m = App::main()) m->ui_showPeerHistory(peer, msgId, back);
|
||||||
}
|
}
|
||||||
|
@ -133,6 +211,29 @@ namespace Ui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PeerData *getPeerForMouseAction() {
|
||||||
|
if (Window *w = App::wnd()) {
|
||||||
|
return w->ui_getPeerForMouseAction();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hideWindowNoQuit() {
|
||||||
|
if (!App::quitting()) {
|
||||||
|
if (Window *w = App::wnd()) {
|
||||||
|
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||||
|
return w->minimizeToTray();
|
||||||
|
} else if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
|
w->hide();
|
||||||
|
w->updateIsActive(Global::OfflineBlurTimeout());
|
||||||
|
w->updateGlobalMenu();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Notify {
|
namespace Notify {
|
||||||
|
@ -153,6 +254,12 @@ namespace Notify {
|
||||||
if (MainWidget *m = App::main()) m->notify_inlineBotRequesting(requesting);
|
if (MainWidget *m = App::main()) m->notify_inlineBotRequesting(requesting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void replyMarkupUpdated(const HistoryItem *item) {
|
||||||
|
if (MainWidget *m = App::main()) {
|
||||||
|
m->notify_replyMarkupUpdated(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void migrateUpdated(PeerData *peer) {
|
void migrateUpdated(PeerData *peer) {
|
||||||
if (MainWidget *m = App::main()) m->notify_migrateUpdated(peer);
|
if (MainWidget *m = App::main()) m->notify_migrateUpdated(peer);
|
||||||
}
|
}
|
||||||
|
@ -161,10 +268,6 @@ namespace Notify {
|
||||||
if (MainWidget *m = App::main()) m->notify_clipStopperHidden(type);
|
if (MainWidget *m = App::main()) m->notify_clipStopperHidden(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void historyItemResized(const HistoryItem *item, bool scrollToIt) {
|
|
||||||
if (MainWidget *m = App::main()) m->notify_historyItemResized(item, scrollToIt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void historyItemLayoutChanged(const HistoryItem *item) {
|
void historyItemLayoutChanged(const HistoryItem *item) {
|
||||||
if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item);
|
if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item);
|
||||||
}
|
}
|
||||||
|
@ -173,4 +276,263 @@ namespace Notify {
|
||||||
if (MainWidget *m = App::main()) m->notify_automaticLoadSettingsChangedGif();
|
if (MainWidget *m = App::main()) m->notify_automaticLoadSettingsChangedGif();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handlePendingHistoryUpdate() {
|
||||||
|
if (MainWidget *m = App::main()) {
|
||||||
|
m->notify_handlePendingHistoryUpdate();
|
||||||
|
}
|
||||||
|
for_const (HistoryItem *item, Global::PendingRepaintItems()) {
|
||||||
|
Ui::repaintHistoryItem(item);
|
||||||
|
}
|
||||||
|
Global::RefPendingRepaintItems().clear();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DefineReadOnlyVar(Namespace, Type, Name) const Type &Name() { \
|
||||||
|
t_assert_full(Namespace##Data != 0, #Namespace "Data != nullptr in " #Namespace "::" #Name, __FILE__, __LINE__); \
|
||||||
|
return Namespace##Data->Name; \
|
||||||
|
}
|
||||||
|
#define DefineRefVar(Namespace, Type, Name) DefineReadOnlyVar(Namespace, Type, Name) \
|
||||||
|
Type &Ref##Name() { \
|
||||||
|
t_assert_full(Namespace##Data != 0, #Namespace "Data != nullptr in " #Namespace "::Ref" #Name, __FILE__, __LINE__); \
|
||||||
|
return Namespace##Data->Name; \
|
||||||
|
}
|
||||||
|
#define DefineVar(Namespace, Type, Name) DefineRefVar(Namespace, Type, Name) \
|
||||||
|
void Set##Name(const Type &Name) { \
|
||||||
|
t_assert_full(Namespace##Data != 0, #Namespace "Data != nullptr in " #Namespace "::Set" #Name, __FILE__, __LINE__); \
|
||||||
|
Namespace##Data->Name = Name; \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Sandbox {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
QString LangSystemISO;
|
||||||
|
int32 LangSystem = languageDefault;
|
||||||
|
|
||||||
|
QByteArray LastCrashDump;
|
||||||
|
ConnectionProxy PreLaunchProxy;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Sandbox::internal::Data *SandboxData = 0;
|
||||||
|
uint64 SandboxUserTag = 0;
|
||||||
|
|
||||||
|
namespace Sandbox {
|
||||||
|
|
||||||
|
bool CheckBetaVersionDir() {
|
||||||
|
QFile beta(cExeDir() + qsl("TelegramBeta_data/tdata/beta"));
|
||||||
|
if (cBetaVersion()) {
|
||||||
|
cForceWorkingDir(cExeDir() + qsl("TelegramBeta_data/"));
|
||||||
|
QDir().mkpath(cWorkingDir() + qstr("tdata"));
|
||||||
|
if (*BetaPrivateKey) {
|
||||||
|
cSetBetaPrivateKey(QByteArray(BetaPrivateKey));
|
||||||
|
}
|
||||||
|
if (beta.open(QIODevice::WriteOnly)) {
|
||||||
|
QDataStream dataStream(&beta);
|
||||||
|
dataStream.setVersion(QDataStream::Qt_5_3);
|
||||||
|
dataStream << quint64(cRealBetaVersion()) << cBetaPrivateKey();
|
||||||
|
} else {
|
||||||
|
LOG(("FATAL: Could not open '%1' for writing private key!").arg(beta.fileName()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (beta.exists()) {
|
||||||
|
cForceWorkingDir(cExeDir() + qsl("TelegramBeta_data/"));
|
||||||
|
if (beta.open(QIODevice::ReadOnly)) {
|
||||||
|
QDataStream dataStream(&beta);
|
||||||
|
dataStream.setVersion(QDataStream::Qt_5_3);
|
||||||
|
|
||||||
|
quint64 v;
|
||||||
|
QByteArray k;
|
||||||
|
dataStream >> v >> k;
|
||||||
|
if (dataStream.status() == QDataStream::Ok) {
|
||||||
|
cSetBetaVersion(qMax(v, AppVersion * 1000ULL));
|
||||||
|
cSetBetaPrivateKey(k);
|
||||||
|
cSetRealBetaVersion(v);
|
||||||
|
} else {
|
||||||
|
LOG(("FATAL: '%1' is corrupted, reinstall private beta!").arg(beta.fileName()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(("FATAL: could not open '%1' for reading private key!").arg(beta.fileName()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkingDirReady() {
|
||||||
|
if (QFile(cWorkingDir() + qsl("tdata/withtestmode")).exists()) {
|
||||||
|
cSetTestMode(true);
|
||||||
|
}
|
||||||
|
if (!cDebug() && QFile(cWorkingDir() + qsl("tdata/withdebug")).exists()) {
|
||||||
|
cSetDebug(true);
|
||||||
|
}
|
||||||
|
if (cBetaVersion()) {
|
||||||
|
cSetDevVersion(false);
|
||||||
|
} else if (!cDevVersion() && QFile(cWorkingDir() + qsl("tdata/devversion")).exists()) {
|
||||||
|
cSetDevVersion(true);
|
||||||
|
} else if (DevVersion) {
|
||||||
|
QFile f(cWorkingDir() + qsl("tdata/devversion"));
|
||||||
|
if (!f.exists() && f.open(QIODevice::WriteOnly)) {
|
||||||
|
f.write("1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srand((int32)time(NULL));
|
||||||
|
|
||||||
|
SandboxUserTag = 0;
|
||||||
|
QFile usertag(cWorkingDir() + qsl("tdata/usertag"));
|
||||||
|
if (usertag.open(QIODevice::ReadOnly)) {
|
||||||
|
if (usertag.read(reinterpret_cast<char*>(&SandboxUserTag), sizeof(uint64)) != sizeof(uint64)) {
|
||||||
|
SandboxUserTag = 0;
|
||||||
|
}
|
||||||
|
usertag.close();
|
||||||
|
}
|
||||||
|
if (!SandboxUserTag) {
|
||||||
|
do {
|
||||||
|
memsetrnd_bad(SandboxUserTag);
|
||||||
|
} while (!SandboxUserTag);
|
||||||
|
|
||||||
|
if (usertag.open(QIODevice::WriteOnly)) {
|
||||||
|
usertag.write(reinterpret_cast<char*>(&SandboxUserTag), sizeof(uint64));
|
||||||
|
usertag.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
SandboxData = new internal::Data();
|
||||||
|
|
||||||
|
SandboxData->LangSystemISO = psCurrentLanguage();
|
||||||
|
if (SandboxData->LangSystemISO.isEmpty()) SandboxData->LangSystemISO = qstr("en");
|
||||||
|
QByteArray l = LangSystemISO().toLatin1();
|
||||||
|
for (int32 i = 0; i < languageCount; ++i) {
|
||||||
|
if (l.at(0) == LanguageCodes[i][0] && l.at(1) == LanguageCodes[i][1]) {
|
||||||
|
SandboxData->LangSystem = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish() {
|
||||||
|
delete SandboxData;
|
||||||
|
SandboxData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 UserTag() {
|
||||||
|
return SandboxUserTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineReadOnlyVar(Sandbox, QString, LangSystemISO);
|
||||||
|
DefineReadOnlyVar(Sandbox, int32, LangSystem);
|
||||||
|
DefineVar(Sandbox, QByteArray, LastCrashDump);
|
||||||
|
DefineVar(Sandbox, ConnectionProxy, PreLaunchProxy);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Global {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
uint64 LaunchId = 0;
|
||||||
|
SingleDelayedCall HandleHistoryUpdate = { App::app(), "call_handleHistoryUpdate" };
|
||||||
|
|
||||||
|
Adaptive::Layout AdaptiveLayout = Adaptive::NormalLayout;
|
||||||
|
bool AdaptiveForWide = true;
|
||||||
|
|
||||||
|
int32 DebugLoggingFlags = 0;
|
||||||
|
|
||||||
|
// config
|
||||||
|
int32 ChatSizeMax = 200;
|
||||||
|
int32 MegagroupSizeMax = 1000;
|
||||||
|
int32 ForwardedCountMax = 100;
|
||||||
|
int32 OnlineUpdatePeriod = 120000;
|
||||||
|
int32 OfflineBlurTimeout = 5000;
|
||||||
|
int32 OfflineIdleTimeout = 30000;
|
||||||
|
int32 OnlineFocusTimeout = 1000;
|
||||||
|
int32 OnlineCloudTimeout = 300000;
|
||||||
|
int32 NotifyCloudDelay = 30000;
|
||||||
|
int32 NotifyDefaultDelay = 1500;
|
||||||
|
int32 ChatBigSize = 10;
|
||||||
|
int32 PushChatPeriod = 60000;
|
||||||
|
int32 PushChatLimit = 2;
|
||||||
|
int32 SavedGifsLimit = 200;
|
||||||
|
int32 EditTimeLimit = 172800;
|
||||||
|
|
||||||
|
HiddenPinnedMessagesMap HiddenPinnedMessages;
|
||||||
|
|
||||||
|
PendingItemsMap PendingRepaintItems;
|
||||||
|
|
||||||
|
Stickers::Sets StickerSets;
|
||||||
|
Stickers::Order StickerSetsOrder;
|
||||||
|
uint64 LastStickersUpdate = 0;
|
||||||
|
|
||||||
|
MTP::DcOptions DcOptions;
|
||||||
|
|
||||||
|
CircleMasksMap CircleMasks;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Global::internal::Data *GlobalData = 0;
|
||||||
|
|
||||||
|
namespace Global {
|
||||||
|
|
||||||
|
bool started() {
|
||||||
|
return GlobalData != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
GlobalData = new internal::Data();
|
||||||
|
|
||||||
|
memset_rand(&GlobalData->LaunchId, sizeof(GlobalData->LaunchId));
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish() {
|
||||||
|
delete GlobalData;
|
||||||
|
GlobalData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineReadOnlyVar(Global, uint64, LaunchId);
|
||||||
|
DefineRefVar(Global, SingleDelayedCall, HandleHistoryUpdate);
|
||||||
|
|
||||||
|
DefineVar(Global, Adaptive::Layout, AdaptiveLayout);
|
||||||
|
DefineVar(Global, bool, AdaptiveForWide);
|
||||||
|
|
||||||
|
DefineVar(Global, int32, DebugLoggingFlags);
|
||||||
|
|
||||||
|
// config
|
||||||
|
DefineVar(Global, int32, ChatSizeMax);
|
||||||
|
DefineVar(Global, int32, MegagroupSizeMax);
|
||||||
|
DefineVar(Global, int32, ForwardedCountMax);
|
||||||
|
DefineVar(Global, int32, OnlineUpdatePeriod);
|
||||||
|
DefineVar(Global, int32, OfflineBlurTimeout);
|
||||||
|
DefineVar(Global, int32, OfflineIdleTimeout);
|
||||||
|
DefineVar(Global, int32, OnlineFocusTimeout);
|
||||||
|
DefineVar(Global, int32, OnlineCloudTimeout);
|
||||||
|
DefineVar(Global, int32, NotifyCloudDelay);
|
||||||
|
DefineVar(Global, int32, NotifyDefaultDelay);
|
||||||
|
DefineVar(Global, int32, ChatBigSize);
|
||||||
|
DefineVar(Global, int32, PushChatPeriod);
|
||||||
|
DefineVar(Global, int32, PushChatLimit);
|
||||||
|
DefineVar(Global, int32, SavedGifsLimit);
|
||||||
|
DefineVar(Global, int32, EditTimeLimit);
|
||||||
|
|
||||||
|
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);
|
||||||
|
|
||||||
|
DefineRefVar(Global, PendingItemsMap, PendingRepaintItems);
|
||||||
|
|
||||||
|
DefineVar(Global, Stickers::Sets, StickerSets);
|
||||||
|
DefineVar(Global, Stickers::Order, StickerSetsOrder);
|
||||||
|
DefineVar(Global, uint64, LastStickersUpdate);
|
||||||
|
|
||||||
|
DefineVar(Global, MTP::DcOptions, DcOptions);
|
||||||
|
|
||||||
|
DefineRefVar(Global, CircleMasksMap, CircleMasks);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -24,10 +24,11 @@ class LayeredWidget;
|
||||||
|
|
||||||
namespace App {
|
namespace App {
|
||||||
|
|
||||||
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
void sendBotCommand(PeerData *peer, const QString &cmd, MsgId replyTo = 0);
|
||||||
bool insertBotCommand(const QString &cmd, bool specialGif = false);
|
bool insertBotCommand(const QString &cmd, bool specialGif = false);
|
||||||
|
void activateBotCommand(const HistoryItem *msg, int row, int col);
|
||||||
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
||||||
void openPeerByName(const QString &username, bool toProfile = false, const QString &startToken = QString());
|
void openPeerByName(const QString &username, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString());
|
||||||
void joinGroupByHash(const QString &hash);
|
void joinGroupByHash(const QString &hash);
|
||||||
void stickersBox(const QString &name);
|
void stickersBox(const QString &name);
|
||||||
void openLocalUrl(const QString &url);
|
void openLocalUrl(const QString &url);
|
||||||
|
@ -35,9 +36,21 @@ namespace App {
|
||||||
void removeDialog(History *history);
|
void removeDialog(History *history);
|
||||||
void showSettings();
|
void showSettings();
|
||||||
|
|
||||||
|
void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
|
||||||
|
|
||||||
|
void logOutDelayed();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Ui { // openssl doesn't allow me to use UI :(
|
namespace InlineBots {
|
||||||
|
namespace Layout {
|
||||||
|
|
||||||
|
class ItemBase;
|
||||||
|
|
||||||
|
} // namespace Layout
|
||||||
|
} // namespace InlineBots
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
void showStickerPreview(DocumentData *sticker);
|
void showStickerPreview(DocumentData *sticker);
|
||||||
void hideStickerPreview();
|
void hideStickerPreview();
|
||||||
|
@ -49,8 +62,9 @@ namespace Ui { // openssl doesn't allow me to use UI :(
|
||||||
bool isInlineItemBeingChosen();
|
bool isInlineItemBeingChosen();
|
||||||
|
|
||||||
void repaintHistoryItem(const HistoryItem *item);
|
void repaintHistoryItem(const HistoryItem *item);
|
||||||
void repaintInlineItem(const LayoutInlineItem *layout);
|
void repaintInlineItem(const InlineBots::Layout::ItemBase *layout);
|
||||||
bool isInlineItemVisible(const LayoutInlineItem *reader);
|
bool isInlineItemVisible(const InlineBots::Layout::ItemBase *reader);
|
||||||
|
void autoplayMediaInlineAsync(const FullMsgId &msgId);
|
||||||
|
|
||||||
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false);
|
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false);
|
||||||
inline void showPeerHistory(const PeerData *peer, MsgId msgId, bool back = false) {
|
inline void showPeerHistory(const PeerData *peer, MsgId msgId, bool back = false) {
|
||||||
|
@ -66,6 +80,12 @@ namespace Ui { // openssl doesn't allow me to use UI :(
|
||||||
inline void showChatsList() {
|
inline void showChatsList() {
|
||||||
showPeerHistory(PeerId(0), 0);
|
showPeerHistory(PeerId(0), 0);
|
||||||
}
|
}
|
||||||
|
inline void showChatsListAsync() {
|
||||||
|
showPeerHistoryAsync(PeerId(0), 0);
|
||||||
|
}
|
||||||
|
PeerData *getPeerForMouseAction();
|
||||||
|
|
||||||
|
bool hideWindowNoQuit();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,17 +101,138 @@ namespace Notify {
|
||||||
void botCommandsChanged(UserData *user);
|
void botCommandsChanged(UserData *user);
|
||||||
|
|
||||||
void inlineBotRequesting(bool requesting);
|
void inlineBotRequesting(bool requesting);
|
||||||
|
void replyMarkupUpdated(const HistoryItem *item);
|
||||||
|
|
||||||
void migrateUpdated(PeerData *peer);
|
void migrateUpdated(PeerData *peer);
|
||||||
|
|
||||||
void clipStopperHidden(ClipStopperType type);
|
void clipStopperHidden(ClipStopperType type);
|
||||||
|
|
||||||
void historyItemResized(const HistoryItem *item, bool scrollToIt = false);
|
|
||||||
inline void historyItemsResized() {
|
|
||||||
historyItemResized(0);
|
|
||||||
}
|
|
||||||
void historyItemLayoutChanged(const HistoryItem *item);
|
void historyItemLayoutChanged(const HistoryItem *item);
|
||||||
|
|
||||||
void automaticLoadSettingsChangedGif();
|
void automaticLoadSettingsChangedGif();
|
||||||
|
|
||||||
|
// handle pending resize() / paint() on history items
|
||||||
|
void handlePendingHistoryUpdate();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
||||||
|
#define DeclareRefVar(Type, Name) DeclareReadOnlyVar(Type, Name) \
|
||||||
|
Type &Ref##Name();
|
||||||
|
#define DeclareVar(Type, Name) DeclareRefVar(Type, Name) \
|
||||||
|
void Set##Name(const Type &Name);
|
||||||
|
|
||||||
|
namespace Sandbox {
|
||||||
|
|
||||||
|
bool CheckBetaVersionDir();
|
||||||
|
void WorkingDirReady();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
uint64 UserTag();
|
||||||
|
|
||||||
|
DeclareReadOnlyVar(QString, LangSystemISO);
|
||||||
|
DeclareReadOnlyVar(int32, LangSystem);
|
||||||
|
DeclareVar(QByteArray, LastCrashDump);
|
||||||
|
DeclareVar(ConnectionProxy, PreLaunchProxy);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Adaptive {
|
||||||
|
enum Layout {
|
||||||
|
OneColumnLayout,
|
||||||
|
NormalLayout,
|
||||||
|
WideLayout,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace DebugLogging {
|
||||||
|
enum Flags {
|
||||||
|
FileLoaderFlag = 0x00000001,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Stickers {
|
||||||
|
static const uint64 DefaultSetId = 0; // for backward compatibility
|
||||||
|
static const uint64 CustomSetId = 0xFFFFFFFFFFFFFFFFULL, RecentSetId = 0xFFFFFFFFFFFFFFFEULL;
|
||||||
|
static const uint64 NoneSetId = 0xFFFFFFFFFFFFFFFDULL; // for emoji/stickers panel
|
||||||
|
struct Set {
|
||||||
|
Set(uint64 id, uint64 access, const QString &title, const QString &shortName, int32 count, int32 hash, MTPDstickerSet::Flags flags) : id(id), access(access), title(title), shortName(shortName), count(count), hash(hash), flags(flags) {
|
||||||
|
}
|
||||||
|
uint64 id, access;
|
||||||
|
QString title, shortName;
|
||||||
|
int32 count, hash;
|
||||||
|
MTPDstickerSet::Flags flags;
|
||||||
|
StickerPack stickers;
|
||||||
|
StickersByEmojiMap emoji;
|
||||||
|
};
|
||||||
|
typedef QMap<uint64, Set> Sets;
|
||||||
|
typedef QList<uint64> Order;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Global {
|
||||||
|
|
||||||
|
bool started();
|
||||||
|
void start();
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
DeclareReadOnlyVar(uint64, LaunchId);
|
||||||
|
DeclareRefVar(SingleDelayedCall, HandleHistoryUpdate);
|
||||||
|
|
||||||
|
DeclareVar(Adaptive::Layout, AdaptiveLayout);
|
||||||
|
DeclareVar(bool, AdaptiveForWide);
|
||||||
|
|
||||||
|
DeclareVar(int32, DebugLoggingFlags);
|
||||||
|
|
||||||
|
// config
|
||||||
|
DeclareVar(int32, ChatSizeMax);
|
||||||
|
DeclareVar(int32, MegagroupSizeMax);
|
||||||
|
DeclareVar(int32, ForwardedCountMax);
|
||||||
|
DeclareVar(int32, OnlineUpdatePeriod);
|
||||||
|
DeclareVar(int32, OfflineBlurTimeout);
|
||||||
|
DeclareVar(int32, OfflineIdleTimeout);
|
||||||
|
DeclareVar(int32, OnlineFocusTimeout); // not from config
|
||||||
|
DeclareVar(int32, OnlineCloudTimeout);
|
||||||
|
DeclareVar(int32, NotifyCloudDelay);
|
||||||
|
DeclareVar(int32, NotifyDefaultDelay);
|
||||||
|
DeclareVar(int32, ChatBigSize);
|
||||||
|
DeclareVar(int32, PushChatPeriod);
|
||||||
|
DeclareVar(int32, PushChatLimit);
|
||||||
|
DeclareVar(int32, SavedGifsLimit);
|
||||||
|
DeclareVar(int32, EditTimeLimit);
|
||||||
|
|
||||||
|
typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap;
|
||||||
|
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);
|
||||||
|
|
||||||
|
typedef OrderedSet<HistoryItem*> PendingItemsMap;
|
||||||
|
DeclareRefVar(PendingItemsMap, PendingRepaintItems);
|
||||||
|
|
||||||
|
DeclareVar(Stickers::Sets, StickerSets);
|
||||||
|
DeclareVar(Stickers::Order, StickerSetsOrder);
|
||||||
|
DeclareVar(uint64, LastStickersUpdate);
|
||||||
|
|
||||||
|
DeclareVar(MTP::DcOptions, DcOptions);
|
||||||
|
|
||||||
|
typedef QMap<uint64, QPixmap> CircleMasksMap;
|
||||||
|
DeclareRefVar(CircleMasksMap, CircleMasks);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Adaptive {
|
||||||
|
inline bool OneColumn() {
|
||||||
|
return Global::AdaptiveLayout() == OneColumnLayout;
|
||||||
|
}
|
||||||
|
inline bool Normal() {
|
||||||
|
return Global::AdaptiveLayout() == NormalLayout;
|
||||||
|
}
|
||||||
|
inline bool Wide() {
|
||||||
|
return Global::AdaptiveForWide() && (Global::AdaptiveLayout() == WideLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace DebugLogging {
|
||||||
|
inline bool FileLoader() {
|
||||||
|
return (Global::DebugLoggingFlags() | FileLoaderFlag) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "fileuploader.h"
|
#include "fileuploader.h"
|
||||||
|
@ -32,7 +32,7 @@ FileUploader::FileUploader() : sentSize(0) {
|
||||||
void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &media) {
|
void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &media) {
|
||||||
if (media.type == PreparePhoto) {
|
if (media.type == PreparePhoto) {
|
||||||
App::feedPhoto(media.photo, media.photoThumbs);
|
App::feedPhoto(media.photo, media.photoThumbs);
|
||||||
} else if (media.type == PrepareDocument) {
|
} else if (media.type == PrepareDocument || media.type == PrepareAudio) {
|
||||||
DocumentData *document;
|
DocumentData *document;
|
||||||
if (media.photoThumbs.isEmpty()) {
|
if (media.photoThumbs.isEmpty()) {
|
||||||
document = App::feedDocument(media.document);
|
document = App::feedDocument(media.document);
|
||||||
|
@ -40,13 +40,12 @@ void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &me
|
||||||
document = App::feedDocument(media.document, media.photoThumbs.begin().value());
|
document = App::feedDocument(media.document, media.photoThumbs.begin().value());
|
||||||
}
|
}
|
||||||
document->status = FileUploading;
|
document->status = FileUploading;
|
||||||
|
if (!media.data.isEmpty()) {
|
||||||
|
document->setData(media.data);
|
||||||
|
}
|
||||||
if (!media.file.isEmpty()) {
|
if (!media.file.isEmpty()) {
|
||||||
document->setLocation(FileLocation(StorageFilePartial, media.file));
|
document->setLocation(FileLocation(StorageFilePartial, media.file));
|
||||||
}
|
}
|
||||||
} else if (media.type == PrepareAudio) {
|
|
||||||
AudioData *audio = App::feedAudio(media.audio);
|
|
||||||
audio->status = FileUploading;
|
|
||||||
audio->setData(media.data);
|
|
||||||
}
|
}
|
||||||
queue.insert(msgId, File(media));
|
queue.insert(msgId, File(media));
|
||||||
sendNext();
|
sendNext();
|
||||||
|
@ -56,7 +55,7 @@ void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file)
|
||||||
if (file->type == PreparePhoto) {
|
if (file->type == PreparePhoto) {
|
||||||
PhotoData *photo = App::feedPhoto(file->photo, file->photoThumbs);
|
PhotoData *photo = App::feedPhoto(file->photo, file->photoThumbs);
|
||||||
photo->uploadingData = new PhotoData::UploadingData(file->partssize);
|
photo->uploadingData = new PhotoData::UploadingData(file->partssize);
|
||||||
} else if (file->type == PrepareDocument) {
|
} else if (file->type == PrepareDocument || file->type == PrepareAudio) {
|
||||||
DocumentData *document;
|
DocumentData *document;
|
||||||
if (file->thumb.isNull()) {
|
if (file->thumb.isNull()) {
|
||||||
document = App::feedDocument(file->document);
|
document = App::feedDocument(file->document);
|
||||||
|
@ -64,13 +63,12 @@ void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file)
|
||||||
document = App::feedDocument(file->document, file->thumb);
|
document = App::feedDocument(file->document, file->thumb);
|
||||||
}
|
}
|
||||||
document->status = FileUploading;
|
document->status = FileUploading;
|
||||||
|
if (!file->content.isEmpty()) {
|
||||||
|
document->setData(file->content);
|
||||||
|
}
|
||||||
if (!file->filepath.isEmpty()) {
|
if (!file->filepath.isEmpty()) {
|
||||||
document->setLocation(FileLocation(StorageFilePartial, file->filepath));
|
document->setLocation(FileLocation(StorageFilePartial, file->filepath));
|
||||||
}
|
}
|
||||||
} else if (file->type == PrepareAudio) {
|
|
||||||
AudioData *audio = App::feedAudio(file->audio);
|
|
||||||
audio->status = FileUploading;
|
|
||||||
audio->setData(file->content);
|
|
||||||
}
|
}
|
||||||
queue.insert(msgId, File(file));
|
queue.insert(msgId, File(file));
|
||||||
sendNext();
|
sendNext();
|
||||||
|
@ -87,12 +85,6 @@ void FileUploader::currentFailed() {
|
||||||
doc->status = FileUploadFailed;
|
doc->status = FileUploadFailed;
|
||||||
}
|
}
|
||||||
emit documentFailed(j.key());
|
emit documentFailed(j.key());
|
||||||
} else if (j->type() == PrepareAudio) {
|
|
||||||
AudioData *audio = App::audio(j->id());
|
|
||||||
if (audio->status == FileUploading) {
|
|
||||||
audio->status = FileUploadFailed;
|
|
||||||
}
|
|
||||||
emit audioFailed(j.key());
|
|
||||||
}
|
}
|
||||||
queue.erase(j);
|
queue.erase(j);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +103,7 @@ void FileUploader::currentFailed() {
|
||||||
|
|
||||||
void FileUploader::killSessions() {
|
void FileUploader::killSessions() {
|
||||||
for (int i = 0; i < MTPUploadSessionsCount; ++i) {
|
for (int i = 0; i < MTPUploadSessionsCount; ++i) {
|
||||||
MTP::stopSession(MTP::upl[i]);
|
MTP::stopSession(MTP::uplDcId(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,24 +140,19 @@ void FileUploader::sendNext() {
|
||||||
if (parts.isEmpty()) {
|
if (parts.isEmpty()) {
|
||||||
if (i->docSentParts >= i->docPartsCount) {
|
if (i->docSentParts >= i->docPartsCount) {
|
||||||
if (requestsSent.isEmpty() && docRequestsSent.isEmpty()) {
|
if (requestsSent.isEmpty() && docRequestsSent.isEmpty()) {
|
||||||
|
bool silent = i->file && i->file->to.silent;
|
||||||
if (i->type() == PreparePhoto) {
|
if (i->type() == PreparePhoto) {
|
||||||
emit photoReady(uploading, MTP_inputFile(MTP_long(i->id()), MTP_int(i->partsCount), MTP_string(i->filename()), MTP_string(i->file ? i->file->filemd5 : i->media.jpeg_md5)));
|
emit photoReady(uploading, silent, MTP_inputFile(MTP_long(i->id()), MTP_int(i->partsCount), MTP_string(i->filename()), MTP_bytes(i->file ? i->file->filemd5 : i->media.jpeg_md5)));
|
||||||
} else if (i->type() == PrepareDocument) {
|
} else if (i->type() == PrepareDocument || i->type() == PrepareAudio) {
|
||||||
QByteArray docMd5(32, Qt::Uninitialized);
|
QByteArray docMd5(32, Qt::Uninitialized);
|
||||||
hashMd5Hex(i->md5Hash.result(), docMd5.data());
|
hashMd5Hex(i->md5Hash.result(), docMd5.data());
|
||||||
|
|
||||||
MTPInputFile doc = (i->docSize > UseBigFilesFrom) ? MTP_inputFileBig(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename())) : MTP_inputFile(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename()), MTP_string(docMd5));
|
MTPInputFile doc = (i->docSize > UseBigFilesFrom) ? MTP_inputFileBig(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename())) : MTP_inputFile(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename()), MTP_bytes(docMd5));
|
||||||
if (i->partsCount) {
|
if (i->partsCount) {
|
||||||
emit thumbDocumentReady(uploading, doc, MTP_inputFile(MTP_long(i->thumbId()), MTP_int(i->partsCount), MTP_string(i->file ? i->file->thumbname : (qsl("thumb.") + i->media.thumbExt)), MTP_string(i->file ? i->file->thumbmd5 : i->media.jpeg_md5)));
|
emit thumbDocumentReady(uploading, silent, doc, MTP_inputFile(MTP_long(i->thumbId()), MTP_int(i->partsCount), MTP_string(i->file ? i->file->thumbname : (qsl("thumb.") + i->media.thumbExt)), MTP_bytes(i->file ? i->file->thumbmd5 : i->media.jpeg_md5)));
|
||||||
} else {
|
} else {
|
||||||
emit documentReady(uploading, doc);
|
emit documentReady(uploading, silent, doc);
|
||||||
}
|
}
|
||||||
} else if (i->type() == PrepareAudio) {
|
|
||||||
QByteArray audioMd5(32, Qt::Uninitialized);
|
|
||||||
hashMd5Hex(i->md5Hash.result(), audioMd5.data());
|
|
||||||
|
|
||||||
MTPInputFile audio = (i->docSize > UseBigFilesFrom) ? MTP_inputFileBig(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename())) : MTP_inputFile(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename()), MTP_string(audioMd5));
|
|
||||||
emit audioReady(uploading, audio);
|
|
||||||
}
|
}
|
||||||
queue.remove(uploading);
|
queue.remove(uploading);
|
||||||
uploading = FullMsgId();
|
uploading = FullMsgId();
|
||||||
|
@ -200,9 +187,9 @@ void FileUploader::sendNext() {
|
||||||
}
|
}
|
||||||
mtpRequestId requestId;
|
mtpRequestId requestId;
|
||||||
if (i->docSize > UseBigFilesFrom) {
|
if (i->docSize > UseBigFilesFrom) {
|
||||||
requestId = MTP::send(MTPupload_SaveBigFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_int(i->docPartsCount), MTP_string(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::upl[todc]);
|
requestId = MTP::send(MTPupload_SaveBigFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_int(i->docPartsCount), MTP_bytes(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::uplDcId(todc));
|
||||||
} else {
|
} else {
|
||||||
requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_string(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::upl[todc]);
|
requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_bytes(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::uplDcId(todc));
|
||||||
}
|
}
|
||||||
docRequestsSent.insert(requestId, i->docSentParts);
|
docRequestsSent.insert(requestId, i->docSentParts);
|
||||||
dcMap.insert(requestId, todc);
|
dcMap.insert(requestId, todc);
|
||||||
|
@ -213,7 +200,7 @@ void FileUploader::sendNext() {
|
||||||
} else {
|
} else {
|
||||||
UploadFileParts::iterator part = parts.begin();
|
UploadFileParts::iterator part = parts.begin();
|
||||||
|
|
||||||
mtpRequestId requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(partsOfId), MTP_int(part.key()), MTP_string(part.value())), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::upl[todc]);
|
mtpRequestId requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(partsOfId), MTP_int(part.key()), MTP_bytes(part.value())), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::uplDcId(todc));
|
||||||
requestsSent.insert(requestId, part.value());
|
requestsSent.insert(requestId, part.value());
|
||||||
dcMap.insert(requestId, todc);
|
dcMap.insert(requestId, todc);
|
||||||
sentSize += part.value().size();
|
sentSize += part.value().size();
|
||||||
|
@ -259,7 +246,7 @@ void FileUploader::clear() {
|
||||||
dcMap.clear();
|
dcMap.clear();
|
||||||
sentSize = 0;
|
sentSize = 0;
|
||||||
for (int32 i = 0; i < MTPUploadSessionsCount; ++i) {
|
for (int32 i = 0; i < MTPUploadSessionsCount; ++i) {
|
||||||
MTP::stopSession(MTP::upl[i]);
|
MTP::stopSession(MTP::uplDcId(i));
|
||||||
sentSizes[i] = 0;
|
sentSizes[i] = 0;
|
||||||
}
|
}
|
||||||
killSessionsTimer.stop();
|
killSessionsTimer.stop();
|
||||||
|
@ -303,7 +290,7 @@ void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
|
||||||
photo->uploadingData->offset = k->fileSentSize;
|
photo->uploadingData->offset = k->fileSentSize;
|
||||||
}
|
}
|
||||||
emit photoProgress(k.key());
|
emit photoProgress(k.key());
|
||||||
} else if (k->type() == PrepareDocument) {
|
} else if (k->type() == PrepareDocument || k->type() == PrepareAudio) {
|
||||||
DocumentData *doc = App::document(k->id());
|
DocumentData *doc = App::document(k->id());
|
||||||
if (doc->uploading()) {
|
if (doc->uploading()) {
|
||||||
doc->uploadOffset = (k->docSentParts - docRequestsSent.size()) * k->docPartSize;
|
doc->uploadOffset = (k->docSentParts - docRequestsSent.size()) * k->docPartSize;
|
||||||
|
@ -312,15 +299,6 @@ void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit documentProgress(k.key());
|
emit documentProgress(k.key());
|
||||||
} else if (k->type() == PrepareAudio) {
|
|
||||||
AudioData *audio = App::audio(k->id());
|
|
||||||
if (audio->uploading()) {
|
|
||||||
audio->uploadOffset = (k->docSentParts - docRequestsSent.size()) * k->docPartSize;
|
|
||||||
if (audio->uploadOffset > audio->size) {
|
|
||||||
audio->uploadOffset = audio->size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit audioProgress(k.key());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -48,18 +48,15 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void photoReady(const FullMsgId &msgId, const MTPInputFile &file);
|
void photoReady(const FullMsgId &msgId, bool silent, const MTPInputFile &file);
|
||||||
void documentReady(const FullMsgId &msgId, const MTPInputFile &file);
|
void documentReady(const FullMsgId &msgId, bool silent, const MTPInputFile &file);
|
||||||
void thumbDocumentReady(const FullMsgId &msgId, const MTPInputFile &file, const MTPInputFile &thumb);
|
void thumbDocumentReady(const FullMsgId &msgId, bool silent, const MTPInputFile &file, const MTPInputFile &thumb);
|
||||||
void audioReady(const FullMsgId &msgId, const MTPInputFile &file);
|
|
||||||
|
|
||||||
void photoProgress(const FullMsgId &msgId);
|
void photoProgress(const FullMsgId &msgId);
|
||||||
void documentProgress(const FullMsgId &msgId);
|
void documentProgress(const FullMsgId &msgId);
|
||||||
void audioProgress(const FullMsgId &msgId);
|
|
||||||
|
|
||||||
void photoFailed(const FullMsgId &msgId);
|
void photoFailed(const FullMsgId &msgId);
|
||||||
void documentFailed(const FullMsgId &msgId);
|
void documentFailed(const FullMsgId &msgId);
|
||||||
void audioFailed(const FullMsgId &msgId);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,19 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include "animation.h"
|
#include "animation.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavformat/avformat.h>
|
||||||
|
#include <libavutil/opt.h>
|
||||||
|
#include <libswscale/swscale.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
@ -93,6 +100,7 @@ namespace anim {
|
||||||
if (!_clipThreads.isEmpty()) {
|
if (!_clipThreads.isEmpty()) {
|
||||||
for (int32 i = 0, l = _clipThreads.size(); i < l; ++i) {
|
for (int32 i = 0, l = _clipThreads.size(); i < l; ++i) {
|
||||||
_clipThreads.at(i)->quit();
|
_clipThreads.at(i)->quit();
|
||||||
|
DEBUG_LOG(("Waiting for clipThread to finish: %1").arg(i));
|
||||||
_clipThreads.at(i)->wait();
|
_clipThreads.at(i)->wait();
|
||||||
delete _clipManagers.at(i);
|
delete _clipManagers.at(i);
|
||||||
delete _clipThreads.at(i);
|
delete _clipThreads.at(i);
|
||||||
|
@ -142,7 +150,7 @@ void AnimationManager::stop(Animation *obj) {
|
||||||
if (_iterating) {
|
if (_iterating) {
|
||||||
_stopping.insert(obj, NullType());
|
_stopping.insert(obj, NullType());
|
||||||
if (!_starting.isEmpty()) {
|
if (!_starting.isEmpty()) {
|
||||||
_starting.insert(obj, NullType());
|
_starting.remove(obj);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AnimatingObjects::iterator i = _objects.find(obj);
|
AnimatingObjects::iterator i = _objects.find(obj);
|
||||||
|
@ -159,7 +167,9 @@ void AnimationManager::timeout() {
|
||||||
_iterating = true;
|
_iterating = true;
|
||||||
uint64 ms = getms();
|
uint64 ms = getms();
|
||||||
for (AnimatingObjects::const_iterator i = _objects.begin(), e = _objects.end(); i != e; ++i) {
|
for (AnimatingObjects::const_iterator i = _objects.begin(), e = _objects.end(); i != e; ++i) {
|
||||||
i.key()->step(ms, true);
|
if (!_stopping.contains(i.key())) {
|
||||||
|
i.key()->step(ms, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_iterating = false;
|
_iterating = false;
|
||||||
|
|
||||||
|
@ -189,18 +199,25 @@ QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, b
|
||||||
bool needOuter = (request.outerw != request.framew) || (request.outerh != request.frameh);
|
bool needOuter = (request.outerw != request.framew) || (request.outerh != request.frameh);
|
||||||
if (badSize || needOuter || hasAlpha || request.rounded) {
|
if (badSize || needOuter || hasAlpha || request.rounded) {
|
||||||
int32 factor(request.factor);
|
int32 factor(request.factor);
|
||||||
bool fill = false;
|
bool newcache = (cache.width() != request.outerw || cache.height() != request.outerh);
|
||||||
if (cache.width() != request.outerw || cache.height() != request.outerh) {
|
if (newcache) {
|
||||||
cache = QImage(request.outerw, request.outerh, QImage::Format_ARGB32_Premultiplied);
|
cache = QImage(request.outerw, request.outerh, QImage::Format_ARGB32_Premultiplied);
|
||||||
if (request.framew < request.outerw || request.frameh < request.outerh || hasAlpha) {
|
|
||||||
fill = true;
|
|
||||||
}
|
|
||||||
cache.setDevicePixelRatio(factor);
|
cache.setDevicePixelRatio(factor);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Painter p(&cache);
|
Painter p(&cache);
|
||||||
if (fill) {
|
if (newcache) {
|
||||||
p.fillRect(0, 0, cache.width() / factor, cache.height() / factor, st::black);
|
if (request.framew < request.outerw) {
|
||||||
|
p.fillRect(0, 0, (request.outerw - request.framew) / (2 * factor), cache.height() / factor, st::black);
|
||||||
|
p.fillRect((request.outerw - request.framew) / (2 * factor) + (request.framew / factor), 0, (cache.width() / factor) - ((request.outerw - request.framew) / (2 * factor) + (request.framew / factor)), cache.height() / factor, st::black);
|
||||||
|
}
|
||||||
|
if (request.frameh < request.outerh) {
|
||||||
|
p.fillRect(qMax(0, (request.outerw - request.framew) / (2 * factor)), 0, qMin(cache.width(), request.framew) / factor, (request.outerh - request.frameh) / (2 * factor), st::black);
|
||||||
|
p.fillRect(qMax(0, (request.outerw - request.framew) / (2 * factor)), (request.outerh - request.frameh) / (2 * factor) + (request.frameh / factor), qMin(cache.width(), request.framew) / factor, (cache.height() / factor) - ((request.outerh - request.frameh) / (2 * factor) + (request.frameh / factor)), st::black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasAlpha) {
|
||||||
|
p.fillRect(qMax(0, (request.outerw - request.framew) / (2 * factor)), qMax(0, (request.outerh - request.frameh) / (2 * factor)), qMin(cache.width(), request.framew) / factor, qMin(cache.height(), request.frameh) / factor, st::white);
|
||||||
}
|
}
|
||||||
QPoint position((request.outerw - request.framew) / (2 * factor), (request.outerh - request.frameh) / (2 * factor));
|
QPoint position((request.outerw - request.framew) / (2 * factor), (request.outerh - request.frameh) / (2 * factor));
|
||||||
if (badSize) {
|
if (badSize) {
|
||||||
|
@ -235,7 +252,7 @@ ClipReader::ClipReader(const FileLocation &location, const QByteArray &data, Cal
|
||||||
_clipManagers.push_back(new ClipReadManager(_clipThreads.back()));
|
_clipManagers.push_back(new ClipReadManager(_clipThreads.back()));
|
||||||
_clipThreads.back()->start();
|
_clipThreads.back()->start();
|
||||||
} else {
|
} else {
|
||||||
_threadIndex = int32(MTP::nonce<uint32>() % _clipThreads.size());
|
_threadIndex = int32(rand_value<uint32>() % _clipThreads.size());
|
||||||
int32 loadLevel = 0x7FFFFFFF;
|
int32 loadLevel = 0x7FFFFFFF;
|
||||||
for (int32 i = 0, l = _clipThreads.size(); i < l; ++i) {
|
for (int32 i = 0, l = _clipThreads.size(); i < l; ++i) {
|
||||||
int32 level = _clipManagers.at(i)->loadLevel();
|
int32 level = _clipManagers.at(i)->loadLevel();
|
||||||
|
@ -369,6 +386,7 @@ QPixmap ClipReader::current(int32 framew, int32 frameh, int32 outerw, int32 oute
|
||||||
frame->request.outerh = outerh * factor;
|
frame->request.outerh = outerh * factor;
|
||||||
|
|
||||||
QImage cacheForResize;
|
QImage cacheForResize;
|
||||||
|
frame->original.setDevicePixelRatio(factor);
|
||||||
frame->pix = QPixmap();
|
frame->pix = QPixmap();
|
||||||
frame->pix = _prepareFrame(frame->request, frame->original, true, cacheForResize);
|
frame->pix = _prepareFrame(frame->request, frame->original, true, cacheForResize);
|
||||||
|
|
||||||
|
@ -418,7 +436,6 @@ void ClipReader::stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipReader::error() {
|
void ClipReader::error() {
|
||||||
_private = 0;
|
|
||||||
_state = ClipError;
|
_state = ClipError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +494,7 @@ public:
|
||||||
, _frameDelay(0) {
|
, _frameDelay(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readNextFrame(QImage &to, bool &hasAlpha, const QSize &size) {
|
bool readNextFrame() {
|
||||||
if (_reader) _frameDelay = _reader->nextImageDelay();
|
if (_reader) _frameDelay = _reader->nextImageDelay();
|
||||||
if (_framesLeft < 1 && !jumpToStart()) {
|
if (_framesLeft < 1 && !jumpToStart()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -587,6 +604,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readNextFrame() {
|
bool readNextFrame() {
|
||||||
|
if (_frameRead) {
|
||||||
|
av_frame_unref(_frame);
|
||||||
|
_frameRead = false;
|
||||||
|
}
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (_avpkt.size > 0) { // previous packet not finished
|
if (_avpkt.size > 0) { // previous packet not finished
|
||||||
|
@ -638,6 +660,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_frame) {
|
if (got_frame) {
|
||||||
|
int64 duration = av_frame_get_pkt_duration(_frame);
|
||||||
|
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
|
||||||
|
int64 frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
||||||
|
_currentFrameDelay = _nextFrameDelay;
|
||||||
|
if (_frameMs + _currentFrameDelay < frameMs) {
|
||||||
|
_currentFrameDelay = int32(frameMs - _frameMs);
|
||||||
|
}
|
||||||
|
if (duration == AV_NOPTS_VALUE) {
|
||||||
|
_nextFrameDelay = 0;
|
||||||
|
} else {
|
||||||
|
_nextFrameDelay = (duration * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
||||||
|
}
|
||||||
|
_frameMs = frameMs;
|
||||||
|
|
||||||
_hadFrame = _frameRead = true;
|
_hadFrame = _frameRead = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -700,20 +736,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 duration = av_frame_get_pkt_duration(_frame);
|
|
||||||
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
|
|
||||||
int64 frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
|
||||||
_currentFrameDelay = _nextFrameDelay;
|
|
||||||
if (_frameMs + _currentFrameDelay < frameMs) {
|
|
||||||
_currentFrameDelay = int32(frameMs - _frameMs);
|
|
||||||
}
|
|
||||||
if (duration == AV_NOPTS_VALUE) {
|
|
||||||
_nextFrameDelay = 0;
|
|
||||||
} else {
|
|
||||||
_nextFrameDelay = (duration * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
|
||||||
}
|
|
||||||
_frameMs = frameMs;
|
|
||||||
|
|
||||||
av_frame_unref(_frame);
|
av_frame_unref(_frame);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -792,6 +814,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
~FFMpegReaderImplementation() {
|
~FFMpegReaderImplementation() {
|
||||||
|
if (_frameRead) {
|
||||||
|
av_frame_unref(_frame);
|
||||||
|
_frameRead = false;
|
||||||
|
}
|
||||||
if (_ioContext) av_free(_ioContext);
|
if (_ioContext) av_free(_ioContext);
|
||||||
if (_codecContext) avcodec_close(_codecContext);
|
if (_codecContext) avcodec_close(_codecContext);
|
||||||
if (_swsContext) sws_freeContext(_swsContext);
|
if (_swsContext) sws_freeContext(_swsContext);
|
||||||
|
|
|
@ -16,11 +16,11 @@ In addition, as a special exception, the copyright holders give permission
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "types.h"
|
#include "basic_types.h"
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
#include <QtGui/QColor>
|
#include <QtGui/QColor>
|
||||||
|
|
||||||
|
@ -208,10 +208,10 @@ class AnimationCreator {
|
||||||
public:
|
public:
|
||||||
AnimationCreator(AnimationImplementation *ptr) : _ptr(ptr) {}
|
AnimationCreator(AnimationImplementation *ptr) : _ptr(ptr) {}
|
||||||
AnimationCreator(const AnimationCreator &other) : _ptr(other.create()) {}
|
AnimationCreator(const AnimationCreator &other) : _ptr(other.create()) {}
|
||||||
AnimationImplementation *create() const { return exchange(_ptr); }
|
AnimationImplementation *create() const { return getPointerAndReset(_ptr); }
|
||||||
~AnimationCreator() { deleteAndMark(_ptr); }
|
~AnimationCreator() { deleteAndMark(_ptr); }
|
||||||
private:
|
private:
|
||||||
AnimationCreator &operator=(const AnimationCreator &other);
|
AnimationCreator &operator=(const AnimationCreator &other) = delete;
|
||||||
mutable AnimationImplementation *_ptr;
|
mutable AnimationImplementation *_ptr;
|
||||||
};
|
};
|
||||||
class AnimationCallbacks {
|
class AnimationCallbacks {
|
||||||
|
@ -222,7 +222,7 @@ public:
|
||||||
~AnimationCallbacks() { deleteAndMark(_implementation); }
|
~AnimationCallbacks() { deleteAndMark(_implementation); }
|
||||||
private:
|
private:
|
||||||
AnimationCallbacks(const AnimationCallbacks &other);
|
AnimationCallbacks(const AnimationCallbacks &other);
|
||||||
AnimationCallbacks &operator=(const AnimationCallbacks &other);
|
AnimationCallbacks &operator=(const AnimationCallbacks &other) = delete;
|
||||||
AnimationImplementation *_implementation;
|
AnimationImplementation *_implementation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue