Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d32e476d96 | ||
|
|
856502a06a | ||
|
|
48ee79ed9d | ||
|
|
1897dad06b | ||
|
|
a95822b2ec | ||
|
|
4cb22530ae | ||
|
|
fa501b18e4 | ||
|
|
9002a49fcc | ||
|
|
6621171e60 | ||
|
|
c16ea77c52 | ||
|
|
efa62ece72 | ||
|
|
869194f16a | ||
|
|
b5c4c34164 | ||
|
|
30e96a1d5e | ||
|
|
82dc07ee42 | ||
|
|
6a41d307bb | ||
|
|
afac237f03 | ||
|
|
8511181508 | ||
|
|
cf9737e762 | ||
|
|
1b16064db6 | ||
|
|
bcd8334263 | ||
|
|
897699dd04 | ||
|
|
3a97bfd110 | ||
|
|
9792d5df76 | ||
|
|
5dd8eab606 | ||
|
|
61729119c5 | ||
|
|
6225bd3bcb | ||
|
|
aabf136690 | ||
|
|
ad8e3f36ad | ||
|
|
0d381870a7 | ||
|
|
2a66ab036c | ||
|
|
af948466f4 | ||
|
|
d50f3f475f | ||
|
|
df78831592 | ||
|
|
a0dc865bdc | ||
|
|
878604225c | ||
|
|
85d0c42d73 | ||
|
|
c89ee8224c | ||
|
|
bf74d02079 | ||
|
|
a9a4623c63 | ||
|
|
b9022ada09 | ||
|
|
f290fef3a3 | ||
|
|
29b8596439 | ||
|
|
14ae657073 | ||
|
|
637b6d9e6e | ||
|
|
86325e889f | ||
|
|
84a790f3cd | ||
|
|
0647bbba0e | ||
|
|
8e1c10463f |
10
QTCREATOR.md
10
QTCREATOR.md
@@ -76,6 +76,16 @@ then go to **/home/user/TBuild/Libraries/openal-soft/build** and run
|
||||
make
|
||||
sudo make install
|
||||
|
||||
####libxkbcommon (required for Fcitx Qt plugin)
|
||||
|
||||
In Terminal go to **/home/user/TBuild/Libraries** and run
|
||||
|
||||
sudo apt-get install xutils-dev bison python-xcbgen
|
||||
git clone https://github.com/xkbcommon/libxkbcommon.git
|
||||
./autogen.sh --disable-x11
|
||||
make
|
||||
sudo make install
|
||||
|
||||
####Qt 5.5.0, slightly patched
|
||||
|
||||
http://download.qt-project.org/official_releases/qt/5.5/5.5.0/single/qt-everywhere-opensource-src-5.5.0.tar.gz
|
||||
|
||||
17
README.md
17
README.md
@@ -6,13 +6,15 @@ Source code is published under GPL v3, license is available [here](https://githu
|
||||
|
||||
###Supported systems
|
||||
|
||||
* Windows XP - Windows 8.1 (**not** RT)
|
||||
* Mac OS X 10.7 - Mac OS X 10.10
|
||||
* Windows XP - Windows 10 (**not** RT)
|
||||
* Mac OS X 10.8 - Mac OS X 10.10
|
||||
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
|
||||
* Ubuntu 12.04 - Ubuntu 14.04
|
||||
* Fedora 22
|
||||
|
||||
###Third-party
|
||||
|
||||
* Qt 5.5.0, slightly patched ([LGPL](http://qt-project.org/doc/qt-5/lgpl.html))
|
||||
* Qt 5.3.2 and 5.5.0, slightly patched ([LGPL](http://qt-project.org/doc/qt-5/lgpl.html))
|
||||
* OpenSSL 1.0.1g ([OpenSSL License](https://www.openssl.org/source/license.html))
|
||||
* zlib 1.2.8 ([zlib License](http://www.zlib.net/zlib_license.html))
|
||||
* libexif 0.6.20 ([LGPL](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html))
|
||||
@@ -27,6 +29,8 @@ Source code is published under GPL v3, license is available [here](https://githu
|
||||
|
||||
###[Build instructions for XCode 6.4](https://github.com/telegramdesktop/tdesktop/blob/master/XCODE.md)
|
||||
|
||||
###[Build instructions for XCode 6.4 for OS X 10.6 and 10.7](https://github.com/telegramdesktop/tdesktop/blob/master/XCODEold.md)
|
||||
|
||||
###[Build instructions for Qt Creator 3.2.0 Ubuntu](https://github.com/telegramdesktop/tdesktop/blob/master/QTCREATOR.md)
|
||||
|
||||
##Projects in Telegram solution
|
||||
@@ -58,15 +62,12 @@ for Mac:
|
||||
|
||||
####MetaEmoji
|
||||
|
||||
from two folders
|
||||
* SourceFiles/art/Emoji
|
||||
* SourceFiles/art/Emoji_200x
|
||||
|
||||
and some inner config creates four sprites and text2emoji replace code
|
||||
creates four sprites and text2emoji replace code
|
||||
* SourceFiles/art/emoji.png
|
||||
* SourceFiles/art/emoji_125x.png
|
||||
* SourceFiles/art/emoji_150x.png
|
||||
* SourceFiles/art/emoji_200x.png
|
||||
* SourceFiles/art/emoji_250x.png
|
||||
* SourceFiles/gui/emoji_config.cpp
|
||||
|
||||
####MetaStyle
|
||||
|
||||
@@ -17,6 +17,16 @@ if [ ! -f "./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmac32upd$AppVersion" ]; then
|
||||
echo "tmac32upd$AppVersion not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup32.$AppVersionStr$DevPostfix.dmg" ]; then
|
||||
echo "tsetup32.$AppVersionStr$DevPostfix.dmg not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tupdate$AppVersion" ]; then
|
||||
echo "tupdate$AppVersion not found!"
|
||||
exit 1
|
||||
@@ -38,6 +48,8 @@ fi
|
||||
|
||||
scp ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmacupd$AppVersion tmaster:tdesktop/www/tmac/
|
||||
scp ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg tmaster:tdesktop/www/tmac/
|
||||
scp ./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmac32upd$AppVersion tmaster:tdesktop/www/tmac32/
|
||||
scp ./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup32.$AppVersionStr$DevPostfix.dmg tmaster:tdesktop/www/tmac32/
|
||||
scp ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tupdate$AppVersion tmaster:tdesktop/www/tsetup/
|
||||
scp ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tportable.$AppVersionStr$DevPostfix.zip tmaster:tdesktop/www/tsetup/
|
||||
scp ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.exe tmaster:tdesktop/www/tsetup/
|
||||
@@ -47,4 +59,7 @@ mv -v ./../../tother/tsetup/$AppVersionStrMajor/$AppVersionStr$DevPostfix ./../.
|
||||
cp -v ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmacupd$AppVersion ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -rv ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram.app.dSYM ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tmac32upd$AppVersion ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -v ./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup32.$AppVersionStr$DevPostfix.dmg ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
cp -rv ./../../tother/tmac32/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram.app.dSYM ./../../../Dropbox/Telegram/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram32.app.dSYM
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ if [ ! -d "./../Linux/Release/deploy/$AppVersionStrMajor" ]; then
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor"
|
||||
fi
|
||||
|
||||
echo "Copying Telegram, Updater and tlinuxupd$AppVersion to deploy/$AppVersionStr$DevPostfix..";
|
||||
echo "Copying Telegram, Updater and tlinuxupd$AppVersion to deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix..";
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram"
|
||||
mv ./../Linux/Release/Telegram ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram/
|
||||
|
||||
@@ -46,7 +46,7 @@ if [ ! -d "./../Linux/Release/deploy/$AppVersionStrMajor" ]; then
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor"
|
||||
fi
|
||||
|
||||
echo "Copying Telegram, Updater and tlinux32upd$AppVersion to deploy/$AppVersionStr$DevPostfix..";
|
||||
echo "Copying Telegram, Updater and tlinux32upd$AppVersion to deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix..";
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix"
|
||||
mkdir "./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram"
|
||||
mv ./../Linux/Release/Telegram ./../Linux/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/Telegram/
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@echo OFF
|
||||
|
||||
set "AppVersionStrMajor=0.8"
|
||||
set "AppVersion=8043"
|
||||
set "AppVersionStrSmall=0.8.43"
|
||||
set "AppVersionStr=0.8.43"
|
||||
set "AppVersionStrFull=0.8.43.0"
|
||||
set "DevChannel=0"
|
||||
set "AppVersion=8050"
|
||||
set "AppVersionStrSmall=0.8.50"
|
||||
set "AppVersionStr=0.8.50"
|
||||
set "AppVersionStrFull=0.8.50.0"
|
||||
set "DevChannel=1"
|
||||
|
||||
if %DevChannel% neq 0 goto preparedev
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_open_from_tray" = "Open Telegram";
|
||||
"lng_minimize_to_tray" = "Minimize to tray";
|
||||
"lng_quit_from_tray" = "Quit Telegram";
|
||||
"lng_tray_icon_text" = "Telegram is still running here,\nyou can change this from settings page.\n\nIf this icon disappears from tray menu,\nyou can drag it back here from hidden icons.";
|
||||
"lng_tray_icon_text" = "Telegram is still running here,\nyou can change this from settings page.\nIf this icon disappears from tray menu,\nyou can drag it here from hidden icons.";
|
||||
|
||||
"lng_month1" = "January";
|
||||
"lng_month2" = "February";
|
||||
@@ -69,6 +69,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "Try now";
|
||||
|
||||
"lng_status_service_notifications" = "service notifications";
|
||||
"lng_status_support" = "support";
|
||||
"lng_status_bot" = "bot";
|
||||
"lng_status_bot_reads_all" = "has access to messages";
|
||||
"lng_status_bot_not_reads_all" = "has no access to messages";
|
||||
@@ -156,8 +157,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_dlg_new_group_name" = "Group name";
|
||||
"lng_dlg_create_group" = "Create";
|
||||
"lng_no_contacts" = "You have no contacts";
|
||||
"lng_no_chats" = "Your chats will be here";
|
||||
"lng_contacts_loading" = "Loading..";
|
||||
"lng_contacts_not_found" = "No contacts found";
|
||||
"lng_dlg_search_chat" = "Search in this chat";
|
||||
"lng_dlg_search_for_messages" = "Search for messages";
|
||||
|
||||
"lng_settings_save" = "Save";
|
||||
"lng_settings_upload" = "Set Profile Photo";
|
||||
@@ -182,6 +186,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_desktop_notify" = "Desktop notifications";
|
||||
"lng_settings_show_name" = "Show sender's name";
|
||||
"lng_settings_show_preview" = "Show message preview";
|
||||
"lng_settings_use_windows" = "Use Windows notifications";
|
||||
"lng_settings_sound_notify" = "Play sound";
|
||||
|
||||
"lng_notification_preview" = "You have a new message";
|
||||
@@ -320,6 +325,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_reset_one_sure" = "Do you want to terminate this session?";
|
||||
"lng_settings_reset_button" = "Terminate";
|
||||
"lng_settings_reset_done" = "Other sessions terminated";
|
||||
"lng_settings_ask_question" = "Ask a Question";
|
||||
"lng_settings_ask_sure" = "Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.\n\nPlease take a look at the Telegram FAQ: it has important troubleshooting tips and answers to most questions.";
|
||||
"lng_settings_faq_button" = "Go to FAQ";
|
||||
"lng_settings_ask_ok" = "Ask";
|
||||
"lng_settings_faq" = "Telegram FAQ";
|
||||
"lng_settings_logout" = "Log Out";
|
||||
"lng_sure_logout" = "Are you sure you want to log out?";
|
||||
|
||||
@@ -339,6 +349,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_topbar_info" = "Info";
|
||||
"lng_profile_about_section" = "About";
|
||||
"lng_profile_settings_section" = "Settings";
|
||||
"lng_profile_actions_section" = "Actions";
|
||||
"lng_profile_bot_settings" = "Settings";
|
||||
"lng_profile_bot_help" = "Help";
|
||||
"lng_profile_participants_section" = "Members";
|
||||
@@ -348,6 +359,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_edit_contact" = "Edit";
|
||||
"lng_profile_enable_notifications" = "Notifications";
|
||||
"lng_profile_clear_history" = "Clear history";
|
||||
"lng_profile_delete_conversation" = "Delete conversation";
|
||||
"lng_profile_clear_and_exit" = "Delete and exit";
|
||||
"lng_profile_search_messages" = "Search for messages";
|
||||
"lng_profile_block_user" = "Block user";
|
||||
"lng_profile_unblock_user" = "Unblock user";
|
||||
"lng_profile_block_bot" = "Stop and block bot";
|
||||
"lng_profile_unblock_bot" = "Unblock bot";
|
||||
"lng_profile_send_message" = "Send Message";
|
||||
"lng_profile_share_contact" = "Share Contact";
|
||||
"lng_profile_invite_to_group" = "Add to Group";
|
||||
@@ -379,9 +397,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "New Group";
|
||||
|
||||
"lng_failed_add_participant" = "Could not add user. Try again later.";
|
||||
"lng_failed_add_not_mutual" = "Sorry, if a person left a group, only a\nmutual contact can bring them back\n(they need to have your phone\nnumber, and you need theirs).";
|
||||
|
||||
"lng_sure_delete_contact" = "Are you sure, you want to delete {contact} from your contact list?";
|
||||
"lng_sure_delete_history" = "Are you sure, you want to delete all message history with {contact}?\n\nThis action cannot be undone.";
|
||||
"lng_sure_delete_group_history" = "Are you sure, you want to delete all message history in «{group}»?\n\nThis action cannot be undone.";
|
||||
|
||||
"lng_sure_delete_and_exit" = "Are you sure, you want to delete all message history and leave «{group}»?\n\nThis action cannot be undone.";
|
||||
|
||||
@@ -462,10 +482,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_message_ph" = "Write a message..";
|
||||
"lng_record_cancel" = "Release outside this field to cancel";
|
||||
"lng_empty_history" = "";
|
||||
"lng_willbe_history" = "Please select chat to start messaging";
|
||||
"lng_willbe_history" = "Please select a chat to start messaging";
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "You";
|
||||
"lng_bot_description" = "What can this bot do?";
|
||||
"lng_unblock_button" = "Unblock";
|
||||
|
||||
"lng_bot_start" = "Start";
|
||||
"lng_bot_choose_group" = "Choose Group";
|
||||
@@ -478,6 +499,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_user_typing" = "{user} is typing";
|
||||
"lng_users_typing" = "{user} and {second_user} are typing";
|
||||
"lng_many_typing" = "{count:_not_used_|# is|# are} typing";
|
||||
"lng_send_action_record_video" = "recording video";
|
||||
"lng_user_action_record_video" = "{user} is recording video";
|
||||
"lng_send_action_upload_video" = "sending video";
|
||||
"lng_user_action_upload_video" = "{user} is sending video";
|
||||
"lng_send_action_record_audio" = "recording audio";
|
||||
"lng_user_action_record_audio" = "{user} is recording audio";
|
||||
"lng_send_action_upload_audio" = "sending audio";
|
||||
"lng_user_action_upload_audio" = "{user} is sending audio";
|
||||
"lng_send_action_upload_photo" = "sending photo";
|
||||
"lng_user_action_upload_photo" = "{user} is sending photo";
|
||||
"lng_send_action_upload_file" = "sending file";
|
||||
"lng_user_action_upload_file" = "{user} is sending file";
|
||||
"lng_send_action_geo_location" = "picking location";
|
||||
"lng_user_action_geo_location" = "{user} is picking location";
|
||||
"lng_send_action_choose_contact" = "choosing contact";
|
||||
"lng_user_action_choose_contact" = "{user} is choosing contact";
|
||||
"lng_unread_bar" = "{count:_not_used_|# unread message|# unread messages}";
|
||||
|
||||
"lng_maps_point" = "Location";
|
||||
@@ -604,7 +641,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
||||
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
||||
"lng_new_version_text" = "— Improved in-app media playback\n— Bug fixes and other minor improvements";
|
||||
"lng_new_version_text" = "— Block users from their profile page\n— Added support for Windows toast notifications\n— Fixed input methods on Linux (Fcitx and IBus)";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||
|
||||
|
||||
@@ -972,6 +972,11 @@ btnSend: flatButton(btnDefFlat) {
|
||||
font: font(16px);
|
||||
overFont: font(16px);
|
||||
}
|
||||
btnUnblock: flatButton(btnSend) {
|
||||
color: #d15948;
|
||||
overColor: #d15948;
|
||||
downColor: #db6352;
|
||||
}
|
||||
|
||||
btnAttachDocument: iconedButton(btnDefIconed) {
|
||||
icon: sprite(218px, 68px, 24px, 24px);
|
||||
|
||||
@@ -199,6 +199,7 @@ void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) {
|
||||
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
|
||||
|
||||
peer->asUser()->setBotInfo(d.vbot_info);
|
||||
peer->asUser()->blocked = d.vblocked.v ? UserIsBlocked : UserIsNotBlocked;
|
||||
|
||||
_fullPeerRequests.remove(peer);
|
||||
App::clearPeerUpdated(peer);
|
||||
@@ -225,6 +226,23 @@ void ApiWrap::requestPeer(PeerData *peer) {
|
||||
_peerRequests.insert(peer, req);
|
||||
}
|
||||
|
||||
void ApiWrap::requestPeers(const QList<PeerData*> &peers) {
|
||||
QVector<MTPint> chats;
|
||||
QVector<MTPInputUser> users;
|
||||
chats.reserve(peers.size());
|
||||
users.reserve(peers.size());
|
||||
for (QList<PeerData*>::const_iterator i = peers.cbegin(), e = peers.cend(); i != e; ++i) {
|
||||
if (!*i || _fullPeerRequests.contains(*i) || _peerRequests.contains(*i)) continue;
|
||||
if ((*i)->chat) {
|
||||
chats.push_back(MTP_int(App::chatFromPeer((*i)->id)));
|
||||
} else {
|
||||
users.push_back((*i)->asUser()->inputUser);
|
||||
}
|
||||
}
|
||||
if (!chats.isEmpty()) MTP::send(MTPmessages_GetChats(MTP_vector<MTPint>(chats)), rpcDone(&ApiWrap::gotChats));
|
||||
if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers));
|
||||
}
|
||||
|
||||
void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) {
|
||||
_peerRequests.remove(peer);
|
||||
|
||||
@@ -249,6 +267,14 @@ void ApiWrap::gotUser(PeerData *peer, const MTPVector<MTPUser> &result) {
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::gotChats(const MTPmessages_Chats &result) {
|
||||
App::feedChats(result.c_messages_chats().vchats);
|
||||
}
|
||||
|
||||
void ApiWrap::gotUsers(const MTPVector<MTPUser> &result) {
|
||||
App::feedUsers(result);
|
||||
}
|
||||
|
||||
bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
|
||||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
void requestPeers(const QList<PeerData*> &peers);
|
||||
|
||||
void requestWebPageDelayed(WebPageData *page);
|
||||
void clearWebPageRequest(WebPageData *page);
|
||||
@@ -72,6 +73,8 @@ private:
|
||||
|
||||
void gotChat(PeerData *peer, const MTPmessages_Chats &result);
|
||||
void gotUser(PeerData *peer, const MTPVector<MTPUser> &result);
|
||||
void gotChats(const MTPmessages_Chats &result);
|
||||
void gotUsers(const MTPVector<MTPUser> &result);
|
||||
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
||||
PeerRequests _peerRequests;
|
||||
|
||||
|
||||
@@ -289,8 +289,10 @@ namespace App {
|
||||
}
|
||||
|
||||
QString onlineText(UserData *user, int32 now, bool precise) {
|
||||
if (isServiceUser(user->id)) {
|
||||
if (isNotificationsUser(user->id)) {
|
||||
return lang(lng_status_service_notifications);
|
||||
} else if (isServiceUser(user->id)) {
|
||||
return lang(lng_status_support);
|
||||
} else if (user->botInfo) {
|
||||
return lang(lng_status_bot);
|
||||
}
|
||||
@@ -370,8 +372,8 @@ namespace App {
|
||||
|
||||
PeerId peer(peerFromUser(d.vid.v));
|
||||
data = App::user(peer);
|
||||
data->input = MTP_inputPeerContact(d.vid);
|
||||
data->inputUser = MTP_inputUserContact(d.vid);
|
||||
data->input = MTP_inputPeerUser(d.vid, MTP_long(0));
|
||||
data->inputUser = MTP_inputUser(d.vid, MTP_long(0));
|
||||
data->setName(lang(lng_deleted), QString(), QString(), QString());
|
||||
data->setPhoto(MTP_userProfilePhotoEmpty());
|
||||
data->access = UserNoAccess;
|
||||
@@ -389,12 +391,12 @@ namespace App {
|
||||
if (flags & MTPDuser_flag_self) {
|
||||
data->input = MTP_inputPeerSelf();
|
||||
data->inputUser = MTP_inputUserSelf();
|
||||
} else if ((flags & (MTPDuser_flag_contact | MTPDuser_flag_mutual_contact)) || !d.has_access_hash()) {
|
||||
data->input = MTP_inputPeerContact(d.vid);
|
||||
data->inputUser = MTP_inputUserContact(d.vid);
|
||||
} else if (!d.has_access_hash()) {
|
||||
data->input = MTP_inputPeerUser(d.vid, MTP_long((data->access == UserNoAccess) ? 0 : data->access));
|
||||
data->inputUser = MTP_inputUser(d.vid, MTP_long((data->access == UserNoAccess) ? 0 : data->access));
|
||||
} else {
|
||||
data->input = MTP_inputPeerForeign(d.vid, d.vaccess_hash);
|
||||
data->inputUser = MTP_inputUserForeign(d.vid, d.vaccess_hash);
|
||||
data->input = MTP_inputPeerUser(d.vid, d.vaccess_hash);
|
||||
data->inputUser = MTP_inputUser(d.vid, d.vaccess_hash);
|
||||
}
|
||||
if (flags & MTPDuser_flag_deleted) {
|
||||
data->setPhone(QString());
|
||||
@@ -416,6 +418,8 @@ namespace App {
|
||||
bool showPhone = !isServiceUser(data->id) && !(flags & (MTPDuser_flag_self | MTPDuser_flag_contact | MTPDuser_flag_mutual_contact));
|
||||
bool showPhoneChanged = !isServiceUser(data->id) && !(flags & (MTPDuser_flag_self)) && ((showPhone && data->contact) || (!showPhone && !data->contact));
|
||||
|
||||
// see also Local::readPeer
|
||||
|
||||
QString pname = (showPhoneChanged || phoneChanged || nameChanged) ? ((showPhone && !phone.isEmpty()) ? formatPhone(phone) : QString()) : data->nameOrPhone;
|
||||
|
||||
data->setName(fname, lname, pname, uname);
|
||||
@@ -500,7 +504,6 @@ namespace App {
|
||||
data->count = d.vparticipants_count.v;
|
||||
data->left = d.vleft.v;
|
||||
data->forbidden = false;
|
||||
data->access = 0;
|
||||
if (data->version < d.vversion.v) {
|
||||
data->version = d.vversion.v;
|
||||
data->participants = ChatData::Participants();
|
||||
@@ -519,7 +522,6 @@ namespace App {
|
||||
data->count = -1;
|
||||
data->left = false;
|
||||
data->forbidden = true;
|
||||
data->access = 0;
|
||||
} break;
|
||||
case mtpc_geoChat: {
|
||||
const MTPDgeoChat &d(chat.c_geoChat());
|
||||
@@ -760,27 +762,23 @@ namespace App {
|
||||
return ImagePtr();
|
||||
}
|
||||
|
||||
StorageImageLocation imageLocation(int32 w, int32 h, const MTPFileLocation &loc) {
|
||||
if (loc.type() == mtpc_fileLocation) {
|
||||
const MTPDfileLocation &l(loc.c_fileLocation());
|
||||
return StorageImageLocation(w, h, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v);
|
||||
}
|
||||
return StorageImageLocation(w, h, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
StorageImageLocation imageLocation(const MTPPhotoSize &size) {
|
||||
switch (size.type()) {
|
||||
case mtpc_photoSize: {
|
||||
const MTPDphotoSize &d(size.c_photoSize());
|
||||
if (d.vlocation.type() == mtpc_fileLocation) {
|
||||
const MTPDfileLocation &l(d.vlocation.c_fileLocation());
|
||||
return StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v);
|
||||
}
|
||||
return imageLocation(d.vw.v, d.vh.v, d.vlocation);
|
||||
} break;
|
||||
case mtpc_photoCachedSize: {
|
||||
const MTPDphotoCachedSize &d(size.c_photoCachedSize());
|
||||
if (d.vlocation.type() == mtpc_fileLocation) {
|
||||
const MTPDfileLocation &l(d.vlocation.c_fileLocation());
|
||||
const string &s(d.vbytes.c_string().v);
|
||||
QByteArray bytes(s.data(), s.size());
|
||||
return StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v);
|
||||
} else if (d.vlocation.type() == mtpc_fileLocationUnavailable) {
|
||||
const string &s(d.vbytes.c_string().v);
|
||||
QByteArray bytes(s.data(), s.size());
|
||||
return StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0);
|
||||
}
|
||||
return imageLocation(d.vw.v, d.vh.v, d.vlocation);
|
||||
} break;
|
||||
}
|
||||
return StorageImageLocation();
|
||||
@@ -872,14 +870,8 @@ namespace App {
|
||||
if (user->contact > 0) {
|
||||
if (!wasContact) {
|
||||
App::main()->addNewContact(App::userFromPeer(user->id), false);
|
||||
if (user->input.type() != mtpc_inputPeerSelf) user->input = MTP_inputPeerContact(userId);
|
||||
if (user->inputUser.type() != mtpc_inputUserSelf) user->inputUser = MTP_inputUserContact(userId);
|
||||
}
|
||||
} else {
|
||||
if (user->access && user->access != UserNoAccess) {
|
||||
if (user->input.type() != mtpc_inputPeerSelf) user->input = MTP_inputPeerForeign(userId, MTP_long(user->access));
|
||||
if (user->inputUser.type() != mtpc_inputUserSelf) user->inputUser = MTP_inputUserForeign(userId, MTP_long(user->access));
|
||||
}
|
||||
if (user->contact < 0 && !user->phone.isEmpty() && App::userFromPeer(user->id) != MTP::authedId()) {
|
||||
user->contact = 0;
|
||||
}
|
||||
@@ -928,7 +920,7 @@ namespace App {
|
||||
return feedPhoto(photo.c_photo(), convert);
|
||||
} break;
|
||||
case mtpc_photoEmpty: {
|
||||
return App::photoSet(photo.c_photoEmpty().vid.v, convert, 0, 0, 0, ImagePtr(), ImagePtr(), ImagePtr());
|
||||
return App::photoSet(photo.c_photoEmpty().vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr());
|
||||
} break;
|
||||
}
|
||||
return App::photo(0);
|
||||
@@ -972,7 +964,7 @@ namespace App {
|
||||
switch (photo.type()) {
|
||||
case mtpc_photo: {
|
||||
const MTPDphoto &ph(photo.c_photo());
|
||||
return App::photoSet(ph.vid.v, 0, ph.vaccess_hash.v, ph.vuser_id.v, ph.vdate.v, ImagePtr(*thumb, "JPG"), ImagePtr(*medium, "JPG"), ImagePtr(*full, "JPG"));
|
||||
return App::photoSet(ph.vid.v, 0, ph.vaccess_hash.v, ph.vdate.v, ImagePtr(*thumb, "JPG"), ImagePtr(*medium, "JPG"), ImagePtr(*full, "JPG"));
|
||||
} break;
|
||||
case mtpc_photoEmpty: return App::photo(photo.c_photoEmpty().vid.v);
|
||||
}
|
||||
@@ -1027,13 +1019,13 @@ namespace App {
|
||||
}
|
||||
}
|
||||
if (thumb && medium && full) {
|
||||
return App::photoSet(photo.vid.v, convert, photo.vaccess_hash.v, photo.vuser_id.v, photo.vdate.v, App::image(*thumb), App::image(*medium), App::image(*full));
|
||||
return App::photoSet(photo.vid.v, convert, photo.vaccess_hash.v, photo.vdate.v, App::image(*thumb), App::image(*medium), App::image(*full));
|
||||
}
|
||||
return App::photoSet(photo.vid.v, convert, 0, 0, 0, ImagePtr(), ImagePtr(), ImagePtr());
|
||||
return App::photoSet(photo.vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr());
|
||||
}
|
||||
|
||||
VideoData *feedVideo(const MTPDvideo &video, VideoData *convert) {
|
||||
return App::videoSet(video.vid.v, convert, video.vaccess_hash.v, video.vuser_id.v, video.vdate.v, video.vduration.v, video.vw.v, video.vh.v, App::image(video.vthumb), video.vdc_id.v, video.vsize.v);
|
||||
return App::videoSet(video.vid.v, convert, video.vaccess_hash.v, video.vdate.v, video.vduration.v, video.vw.v, video.vh.v, App::image(video.vthumb), video.vdc_id.v, video.vsize.v);
|
||||
}
|
||||
|
||||
AudioData *feedAudio(const MTPaudio &audio, AudioData *convert) {
|
||||
@@ -1042,14 +1034,14 @@ namespace App {
|
||||
return feedAudio(audio.c_audio(), convert);
|
||||
} break;
|
||||
case mtpc_audioEmpty: {
|
||||
return App::audioSet(audio.c_audioEmpty().vid.v, convert, 0, 0, 0, QString(), 0, 0, 0);
|
||||
return App::audioSet(audio.c_audioEmpty().vid.v, convert, 0, 0, QString(), 0, 0, 0);
|
||||
} break;
|
||||
}
|
||||
return App::audio(0);
|
||||
}
|
||||
|
||||
AudioData *feedAudio(const MTPDaudio &audio, AudioData *convert) {
|
||||
return App::audioSet(audio.vid.v, convert, audio.vaccess_hash.v, audio.vuser_id.v, audio.vdate.v, qs(audio.vmime_type), audio.vduration.v, audio.vdc_id.v, audio.vsize.v);
|
||||
return App::audioSet(audio.vid.v, convert, audio.vaccess_hash.v, audio.vdate.v, qs(audio.vmime_type), audio.vduration.v, audio.vdc_id.v, audio.vsize.v);
|
||||
}
|
||||
|
||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb) {
|
||||
@@ -1176,7 +1168,7 @@ namespace App {
|
||||
return i.value();
|
||||
}
|
||||
|
||||
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 user, 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) {
|
||||
if (convert) {
|
||||
if (convert->id != photo) {
|
||||
PhotosData::iterator i = photosData.find(convert->id);
|
||||
@@ -1186,8 +1178,7 @@ namespace App {
|
||||
convert->id = photo;
|
||||
}
|
||||
convert->access = access;
|
||||
if (!convert->user && !convert->date && (user || date)) {
|
||||
convert->user = user;
|
||||
if (!convert->date && date) {
|
||||
convert->date = date;
|
||||
convert->thumb = thumb;
|
||||
convert->medium = medium;
|
||||
@@ -1201,14 +1192,13 @@ namespace App {
|
||||
if (convert) {
|
||||
result = convert;
|
||||
} else {
|
||||
result = new PhotoData(photo, access, user, date, thumb, medium, full);
|
||||
result = new PhotoData(photo, access, date, thumb, medium, full);
|
||||
}
|
||||
photosData.insert(photo, result);
|
||||
} else {
|
||||
result = i.value();
|
||||
if (result != convert && !result->user && !result->date && (user || date)) {
|
||||
if (result != convert && !result->date && date) {
|
||||
result->access = access;
|
||||
result->user = user;
|
||||
result->date = date;
|
||||
result->thumb = thumb;
|
||||
result->medium = medium;
|
||||
@@ -1238,7 +1228,7 @@ namespace App {
|
||||
return i.value();
|
||||
}
|
||||
|
||||
VideoData *videoSet(const VideoId &video, VideoData *convert, const uint64 &access, int32 user, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) {
|
||||
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) {
|
||||
if (convert) {
|
||||
if (convert->id != video) {
|
||||
VideosData::iterator i = videosData.find(convert->id);
|
||||
@@ -1249,8 +1239,7 @@ namespace App {
|
||||
convert->status = FileReady;
|
||||
}
|
||||
convert->access = access;
|
||||
if (!convert->user && !convert->date && (user || date)) {
|
||||
convert->user = user;
|
||||
if (!convert->date && date) {
|
||||
convert->date = date;
|
||||
convert->duration = duration;
|
||||
convert->w = w;
|
||||
@@ -1266,14 +1255,13 @@ namespace App {
|
||||
if (convert) {
|
||||
result = convert;
|
||||
} else {
|
||||
result = new VideoData(video, access, user, date, duration, w, h, thumb, dc, size);
|
||||
result = new VideoData(video, access, date, duration, w, h, thumb, dc, size);
|
||||
}
|
||||
videosData.insert(video, result);
|
||||
} else {
|
||||
result = i.value();
|
||||
if (result != convert && !result->user && !result->date && (user || date)) {
|
||||
if (result != convert && !result->date && date) {
|
||||
result->access = access;
|
||||
result->user = user;
|
||||
result->date = date;
|
||||
result->duration = duration;
|
||||
result->w = w;
|
||||
@@ -1294,7 +1282,7 @@ namespace App {
|
||||
return i.value();
|
||||
}
|
||||
|
||||
AudioData *audioSet(const AudioId &audio, AudioData *convert, const uint64 &access, int32 user, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) {
|
||||
AudioData *audioSet(const AudioId &audio, AudioData *convert, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) {
|
||||
if (convert) {
|
||||
if (convert->id != audio) {
|
||||
AudiosData::iterator i = audiosData.find(convert->id);
|
||||
@@ -1305,8 +1293,7 @@ namespace App {
|
||||
convert->status = FileReady;
|
||||
}
|
||||
convert->access = access;
|
||||
if (!convert->user && !convert->date && (user || date)) {
|
||||
convert->user = user;
|
||||
if (!convert->date && date) {
|
||||
convert->date = date;
|
||||
convert->mime = mime;
|
||||
convert->duration = duration;
|
||||
@@ -1320,14 +1307,13 @@ namespace App {
|
||||
if (convert) {
|
||||
result = convert;
|
||||
} else {
|
||||
result = new AudioData(audio, access, user, date, mime, duration, dc, size);
|
||||
result = new AudioData(audio, access, date, mime, duration, dc, size);
|
||||
}
|
||||
audiosData.insert(audio, result);
|
||||
} else {
|
||||
result = i.value();
|
||||
if (result != convert && !result->user && !result->date && (user || date)) {
|
||||
if (result != convert && !result->date && date) {
|
||||
result->access = access;
|
||||
result->user = user;
|
||||
result->date = date;
|
||||
result->mime = mime;
|
||||
result->duration = duration;
|
||||
@@ -1551,7 +1537,7 @@ namespace App {
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("a"), uphoto.vphoto_small, MTP_int(160), MTP_int(160), MTP_int(0)));
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("c"), uphoto.vphoto_big, MTP_int(640), MTP_int(640), MTP_int(0)));
|
||||
|
||||
return MTP_photo(uphoto.vphoto_id, MTP_long(0), userId, date, MTP_geoPointEmpty(), MTP_vector<MTPPhotoSize>(photoSizes));
|
||||
return MTP_photo(uphoto.vphoto_id, MTP_long(0), date, MTP_vector<MTPPhotoSize>(photoSizes));
|
||||
}
|
||||
return MTP_photoEmpty(MTP_long(0));
|
||||
}
|
||||
@@ -1697,6 +1683,8 @@ namespace App {
|
||||
randomData.clear();
|
||||
mutedPeers.clear();
|
||||
updatedPeers.clear();
|
||||
cSetSavedPeers(SavedPeers());
|
||||
cSetSavedPeersByTime(SavedPeersByTime());
|
||||
for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) {
|
||||
delete *i;
|
||||
}
|
||||
@@ -1752,15 +1740,6 @@ namespace App {
|
||||
}
|
||||
}
|
||||
|
||||
/* // don't delete history without deleting its' peerdata
|
||||
void deleteHistory(const PeerId &peer) {
|
||||
Histories::iterator i = ::histories.find(peer);
|
||||
if (i != ::histories.end()) {
|
||||
::histories.typing.remove(i.value());
|
||||
::histories.erase(i);
|
||||
}
|
||||
}
|
||||
/**/
|
||||
void historyRegRandom(uint64 randomId, MsgId itemId) {
|
||||
randomData.insert(randomId, itemId);
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ namespace App {
|
||||
int32 maxMsgId();
|
||||
|
||||
ImagePtr image(const MTPPhotoSize &size);
|
||||
StorageImageLocation imageLocation(int32 w, int32 h, const MTPFileLocation &loc);
|
||||
StorageImageLocation imageLocation(const MTPPhotoSize &size);
|
||||
|
||||
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
||||
@@ -157,11 +158,11 @@ namespace App {
|
||||
ChatData *chat(int32 chat);
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
PhotoData *photo(const PhotoId &photo);
|
||||
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 user, 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 user, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size);
|
||||
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 user, int32 date, const QString &mime, int32 duration, int32 dc, int32 size);
|
||||
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 *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);
|
||||
@@ -183,7 +184,6 @@ namespace App {
|
||||
void historyClearItems();
|
||||
void historyRegReply(HistoryReply *reply, HistoryItem *to);
|
||||
void historyUnregReply(HistoryReply *reply, HistoryItem *to);
|
||||
// void deleteHistory(const PeerId &peer);
|
||||
|
||||
void historyRegRandom(uint64 randomId, MsgId itemId);
|
||||
void historyUnregRandom(uint64 randomId);
|
||||
|
||||
@@ -110,7 +110,6 @@ Application::Application(int &argc, char **argv) : PsApplication(argc, argv),
|
||||
}
|
||||
mainApp = this;
|
||||
|
||||
|
||||
installEventFilter(new EventFilterForKeys(this));
|
||||
|
||||
QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/OpenSans-Regular.ttf"));
|
||||
@@ -474,7 +473,7 @@ void Application::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId)
|
||||
|
||||
PhotoId id = MTP::nonce<PhotoId>();
|
||||
|
||||
MTPPhoto photo(MTP_photo(MTP_long(id), MTP_long(0), MTP_int(MTP::authedId()), MTP_int(unixtime()), MTP_geoPointEmpty(), MTP_vector<MTPPhotoSize>(photoSizes)));
|
||||
MTPPhoto photo(MTP_photo(MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_vector<MTPPhotoSize>(photoSizes)));
|
||||
|
||||
QString file, filename;
|
||||
int32 filesize = 0;
|
||||
@@ -655,13 +654,12 @@ void Application::socketError(QLocalSocket::LocalSocketError e) {
|
||||
|
||||
void Application::checkMapVersion() {
|
||||
if (Local::oldMapVersion() < AppVersion) {
|
||||
psRegisterCustomScheme();
|
||||
if (Local::oldMapVersion()) {
|
||||
QString versionFeatures;
|
||||
if (cDevVersion() && Local::oldMapVersion() < 8042) {
|
||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Dev version will now get updated to stable as well");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
} else if (!cDevVersion() && Local::oldMapVersion() < 8043) {
|
||||
versionFeatures = lang(lng_new_version_minor).trimmed();
|
||||
if (cDevVersion() && Local::oldMapVersion() < 8050) {
|
||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Bug fixes in Windows notifications\n\xe2\x80\x94 Fixed input methods on Linux (Fcitx and IBus)");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
} else if (!cDevVersion() && Local::oldMapVersion() < 8048) {
|
||||
versionFeatures = lang(lng_new_version_text).trimmed();
|
||||
}
|
||||
if (!versionFeatures.isEmpty()) {
|
||||
versionFeatures = lng_new_version_wrap(lt_version, QString::fromStdWString(AppVersionStr), lt_changes, versionFeatures, lt_link, qsl("https://desktop.telegram.org/#changelog"));
|
||||
|
||||
@@ -1099,7 +1099,11 @@ public:
|
||||
}
|
||||
|
||||
freq = fmtContext->streams[streamId]->codec->sample_rate;
|
||||
len = (fmtContext->streams[streamId]->duration * freq * fmtContext->streams[streamId]->time_base.num) / fmtContext->streams[streamId]->time_base.den;
|
||||
if (fmtContext->streams[streamId]->duration == AV_NOPTS_VALUE) {
|
||||
len = (fmtContext->duration * freq) / AV_TIME_BASE;
|
||||
} else {
|
||||
len = (fmtContext->streams[streamId]->duration * freq * fmtContext->streams[streamId]->time_base.num) / fmtContext->streams[streamId]->time_base.den;
|
||||
}
|
||||
uint64_t layout = fmtContext->streams[streamId]->codec->channel_layout;
|
||||
inputFormat = fmtContext->streams[streamId]->codec->sample_fmt;
|
||||
switch (layout) {
|
||||
@@ -2221,7 +2225,9 @@ public:
|
||||
int res = 0;
|
||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||
if ((res = avformat_open_input(&fmtContext, 0, 0, 0)) < 0) {
|
||||
DEBUG_LOG(("Audio Read Error: Unable to avformat_open_input for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
ioBuffer = 0;
|
||||
|
||||
DEBUG_LOG(("Audio Read Error: Unable to avformat_open_input for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
return false;
|
||||
}
|
||||
_opened = true;
|
||||
@@ -2244,7 +2250,11 @@ public:
|
||||
}
|
||||
|
||||
freq = fmtContext->streams[streamId]->codec->sample_rate;
|
||||
len = (fmtContext->streams[streamId]->duration * freq) / fmtContext->streams[streamId]->time_base.den;
|
||||
if (fmtContext->streams[streamId]->duration == AV_NOPTS_VALUE) {
|
||||
len = (fmtContext->duration * freq) / AV_TIME_BASE;
|
||||
} else {
|
||||
len = (fmtContext->streams[streamId]->duration * freq * fmtContext->streams[streamId]->time_base.num) / fmtContext->streams[streamId]->time_base.den;
|
||||
}
|
||||
|
||||
for (int32 i = 0, l = fmtContext->nb_streams; i < l; ++i) {
|
||||
AVStream *stream = fmtContext->streams[i];
|
||||
|
||||
@@ -56,19 +56,24 @@ void ConfirmBox::init(const QString &text) {
|
||||
_confirm.hide();
|
||||
_cancel.hide();
|
||||
|
||||
connect(&_close, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
connect(&_close, SIGNAL(clicked()), this, SLOT(onCancel()));
|
||||
|
||||
setMouseTracking(_text.hasLinks());
|
||||
} else {
|
||||
_close.hide();
|
||||
|
||||
connect(&_confirm, SIGNAL(clicked()), this, SIGNAL(confirmed()));
|
||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onCancel()));
|
||||
}
|
||||
|
||||
prepare();
|
||||
}
|
||||
|
||||
void ConfirmBox::onCancel() {
|
||||
emit cancelPressed();
|
||||
onClose();
|
||||
}
|
||||
|
||||
void ConfirmBox::mouseMoveEvent(QMouseEvent *e) {
|
||||
_lastMousePos = e->globalPos();
|
||||
updateHover();
|
||||
|
||||
@@ -35,10 +35,15 @@ public:
|
||||
void leaveEvent(QEvent *e);
|
||||
void updateLink();
|
||||
|
||||
public slots:
|
||||
|
||||
void onCancel();
|
||||
|
||||
signals:
|
||||
|
||||
void confirmed();
|
||||
void cancelled();
|
||||
void cancelPressed();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ _byUsernameSel(-1),
|
||||
_addContactLnk(this, lang(lng_add_contact_button)) {
|
||||
DialogsIndexed &v(App::main()->dialogsList());
|
||||
for (DialogRow *r = v.list.begin; r != v.list.end; r = r->next) {
|
||||
if (r->history->peer->chat && !r->history->peer->asChat()->forbidden) {
|
||||
if (r->history->peer->chat && !r->history->peer->asChat()->forbidden && !r->history->peer->asChat()->left) {
|
||||
_contacts->addToEnd(r->history);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ void ContactsInner::onAddBot() {
|
||||
|
||||
void ContactsInner::peerUpdated(PeerData *peer) {
|
||||
if (_chat && (!peer || peer == _chat)) {
|
||||
if (_chat->forbidden) {
|
||||
if (_chat->forbidden || _chat->left) {
|
||||
App::wnd()->hideLayer();
|
||||
} else if (!_chat->participants.isEmpty() || _chat->count <= 0) {
|
||||
for (ContactsData::iterator i = _contactsData.begin(), e = _contactsData.end(); i != e; ++i) {
|
||||
@@ -180,11 +180,11 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) {
|
||||
if (i == _contactsData.cend()) {
|
||||
_contactsData.insert(peer, data = new ContactData());
|
||||
data->inchat = (_chat && !peer->chat) ? _chat->participants.contains(peer->asUser()) : false;
|
||||
data->check = false;
|
||||
data->check = _checkedContacts.contains(peer);
|
||||
data->name.setText(st::profileListNameFont, peer->name, _textNameOptions);
|
||||
if (peer->chat) {
|
||||
ChatData *chat = peer->asChat();
|
||||
if (chat->forbidden) {
|
||||
if (chat->forbidden || chat->left) {
|
||||
data->online = lang(lng_chat_status_unaccessible);
|
||||
} else {
|
||||
data->online = lng_chat_status_members(lt_count, chat->count);
|
||||
@@ -401,7 +401,7 @@ void ContactsInner::chooseParticipant() {
|
||||
if (_filter.isEmpty()) {
|
||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsername.size()) {
|
||||
if (d_byUsername[_byUsernameSel]->inchat) return;
|
||||
changeCheckState(d_byUsername[_byUsernameSel]);
|
||||
changeCheckState(d_byUsername[_byUsernameSel], _byUsername[_byUsernameSel]);
|
||||
} else {
|
||||
if (!_sel || contactData(_sel)->inchat) return;
|
||||
changeCheckState(_sel);
|
||||
@@ -409,7 +409,7 @@ void ContactsInner::chooseParticipant() {
|
||||
} else {
|
||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsernameFiltered.size()) {
|
||||
if (d_byUsernameFiltered[_byUsernameSel]->inchat) return;
|
||||
changeCheckState(d_byUsernameFiltered[_byUsernameSel]);
|
||||
changeCheckState(d_byUsernameFiltered[_byUsernameSel], _byUsernameFiltered[_byUsernameSel]);
|
||||
|
||||
ContactData *moving = d_byUsernameFiltered[_byUsernameSel];
|
||||
int32 i = 0, l = d_byUsername.size();
|
||||
@@ -470,15 +470,17 @@ void ContactsInner::chooseParticipant() {
|
||||
}
|
||||
|
||||
void ContactsInner::changeCheckState(DialogRow *row) {
|
||||
changeCheckState(contactData(row));
|
||||
changeCheckState(contactData(row), row->history->peer);
|
||||
}
|
||||
|
||||
void ContactsInner::changeCheckState(ContactData *data) {
|
||||
void ContactsInner::changeCheckState(ContactData *data, PeerData *peer) {
|
||||
if (data->check) {
|
||||
data->check = false;
|
||||
_checkedContacts.remove(peer);
|
||||
--_selCount;
|
||||
} else if (_selCount + (_chat ? _chat->count : 0) < cMaxGroupCount()) {
|
||||
data->check = true;
|
||||
_checkedContacts.insert(peer, true);
|
||||
++_selCount;
|
||||
}
|
||||
}
|
||||
@@ -693,7 +695,7 @@ void ContactsInner::peopleReceived(const QString &query, const QVector<MTPContac
|
||||
ContactData *d = new ContactData();
|
||||
_byUsernameDatas.push_back(d);
|
||||
d->inchat = _chat ? _chat->participants.contains(u) : false;
|
||||
d->check = false;
|
||||
d->check = _checkedContacts.contains(u);
|
||||
d->name.setText(st::profileListNameFont, u->name, _textNameOptions);
|
||||
d->online = '@' + u->username;
|
||||
|
||||
@@ -880,6 +882,11 @@ void ContactsInner::selectSkipPage(int32 h, int32 dir) {
|
||||
|
||||
QVector<UserData*> ContactsInner::selected() {
|
||||
QVector<UserData*> result;
|
||||
for (DialogRow *row = _contacts->list.begin; row->next; row = row->next) {
|
||||
if (_checkedContacts.contains(row->history->peer)) {
|
||||
contactData(row); // fill _contactsData
|
||||
}
|
||||
}
|
||||
result.reserve(_contactsData.size());
|
||||
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
||||
if (i.value()->check && !i.key()->chat) {
|
||||
@@ -896,10 +903,15 @@ QVector<UserData*> ContactsInner::selected() {
|
||||
|
||||
QVector<MTPInputUser> ContactsInner::selectedInputs() {
|
||||
QVector<MTPInputUser> result;
|
||||
for (DialogRow *row = _contacts->list.begin; row->next; row = row->next) {
|
||||
if (_checkedContacts.contains(row->history->peer)) {
|
||||
contactData(row); // fill _contactsData
|
||||
}
|
||||
}
|
||||
result.reserve(_contactsData.size());
|
||||
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
||||
if (i.value()->check && !i.key()->chat) {
|
||||
result.push_back(i.key()->inputUser);
|
||||
result.push_back(i.key()->asUser()->inputUser);
|
||||
}
|
||||
}
|
||||
for (int32 i = 0, l = _byUsername.size(); i < l; ++i) {
|
||||
@@ -911,6 +923,11 @@ QVector<MTPInputUser> ContactsInner::selectedInputs() {
|
||||
}
|
||||
|
||||
PeerData *ContactsInner::selectedUser() {
|
||||
for (DialogRow *row = _contacts->list.begin; row->next; row = row->next) {
|
||||
if (_checkedContacts.contains(row->history->peer)) {
|
||||
contactData(row); // fill _contactsData
|
||||
}
|
||||
}
|
||||
for (ContactsData::const_iterator i = _contactsData.cbegin(), e = _contactsData.cend(); i != e; ++i) {
|
||||
if (i.value()->check) {
|
||||
return i.key();
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
void loadProfilePhotos(int32 yFrom);
|
||||
void chooseParticipant();
|
||||
void changeCheckState(DialogRow *row);
|
||||
void changeCheckState(ContactData *data);
|
||||
void changeCheckState(ContactData *data, PeerData *peer);
|
||||
|
||||
void peopleReceived(const QString &query, const QVector<MTPContactFound> &people);
|
||||
|
||||
@@ -109,6 +109,8 @@ private:
|
||||
};
|
||||
typedef QMap<PeerData*, ContactData*> ContactsData;
|
||||
ContactsData _contactsData;
|
||||
typedef QMap<PeerData*, bool> CheckedContacts;
|
||||
CheckedContacts _checkedContacts;
|
||||
|
||||
ContactData *contactData(DialogRow *row);
|
||||
|
||||
|
||||
@@ -190,7 +190,11 @@ void PhotoSendBox::hideAll() {
|
||||
void PhotoSendBox::showAll() {
|
||||
_sendButton.show();
|
||||
_cancelButton.show();
|
||||
_compressed.show();
|
||||
if (_img && _img->type == ToPreparePhoto) {
|
||||
_compressed.show();
|
||||
} else {
|
||||
_compressed.hide();
|
||||
}
|
||||
}
|
||||
|
||||
void PhotoSendBox::onSend(bool ctrlShiftEnter) {
|
||||
|
||||
@@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
static const int32 AppVersion = 8043;
|
||||
static const wchar_t *AppVersionStr = L"0.8.43";
|
||||
static const bool DevVersion = false;
|
||||
static const int32 AppVersion = 8050;
|
||||
static const wchar_t *AppVersionStr = L"0.8.50";
|
||||
static const bool DevVersion = true;
|
||||
|
||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||
static const wchar_t *AppName = L"Telegram Desktop";
|
||||
@@ -144,10 +144,14 @@ enum {
|
||||
ChoosePeerByDragTimeout = 1000, // 1 second mouse not moved to choose dialog when dragging a file
|
||||
};
|
||||
|
||||
inline bool isServiceUser(uint64 id) {
|
||||
inline bool isNotificationsUser(uint64 id) {
|
||||
return (id == 333000) || (id == ServiceUserId);
|
||||
}
|
||||
|
||||
inline bool isServiceUser(uint64 id) {
|
||||
return !(id % 1000);// (id == 333000) || (id == ServiceUserId);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
inline const GUID &cGUID() {
|
||||
static const GUID gGuid = { 0x87a94ab0, 0xe370, 0x4cde, { 0x98, 0xd3, 0xac, 0xc1, 0x10, 0xc5, 0x96, 0x7d } };
|
||||
@@ -321,6 +325,7 @@ enum {
|
||||
MemoryForImageCache = 64 * 1024 * 1024, // after 64mb of unpacked images we try to clear some memory
|
||||
NotifyWindowsCount = 3, // 3 desktop notifies at the same time
|
||||
NotifySettingSaveTimeout = 1000, // wait 1 second before saving notify setting to server
|
||||
NotifyDeletePhotoAfter = 60000, // delete notify photo after 1 minute
|
||||
UpdateChunk = 100 * 1024, // 100kb parts when downloading the update
|
||||
IdleMsecs = 60 * 1000, // after 60secs without user input we think we are idle
|
||||
|
||||
|
||||
@@ -42,12 +42,16 @@ peopleSel(-1),
|
||||
_lastSearchId(0),
|
||||
_state(DefaultState),
|
||||
_addContactLnk(this, lang(lng_add_contact_button)),
|
||||
_overDelete(false) {
|
||||
_cancelSearchInPeer(this, st::btnCancelSearch),
|
||||
_overDelete(false),
|
||||
_searchInPeer(0) {
|
||||
connect(main, SIGNAL(dialogToTop(const History::DialogLinks&)), this, SLOT(onDialogToTop(const History::DialogLinks&)));
|
||||
connect(main, SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)));
|
||||
connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*)));
|
||||
connect(main, SIGNAL(dialogRowReplaced(DialogRow*,DialogRow*)), this, SLOT(onDialogRowReplaced(DialogRow*,DialogRow*)));
|
||||
connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
|
||||
connect(&_cancelSearchInPeer, SIGNAL(clicked()), this, SIGNAL(cancelSearchInPeer()));
|
||||
_cancelSearchInPeer.hide();
|
||||
refresh(false);
|
||||
}
|
||||
|
||||
@@ -60,7 +64,9 @@ int32 DialogsListWidget::peopleOffset() const {
|
||||
}
|
||||
|
||||
int32 DialogsListWidget::searchedOffset() const {
|
||||
return peopleOffset() + (peopleResults.isEmpty() ? 0 : ((peopleResults.size() * st::dlgHeight) + st::searchedBarHeight));
|
||||
int32 result = peopleOffset() + (peopleResults.isEmpty() ? 0 : ((peopleResults.size() * st::dlgHeight) + st::searchedBarHeight));
|
||||
if (_searchInPeer) result += st::dlgHeight;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DialogsListWidget::paintEvent(QPaintEvent *e) {
|
||||
@@ -80,12 +86,12 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) {
|
||||
if (otherStart) {
|
||||
dialogs.list.paint(p, width(), r.top(), r.bottom(), active, selected);
|
||||
}
|
||||
if (contactsNoDialogs.list.count) {
|
||||
if (contactsNoDialogs.list.count && false) {
|
||||
contactsNoDialogs.list.paint(p, width(), r.top() - otherStart, r.bottom() - otherStart, active, selected);
|
||||
} else if (!otherStart) {
|
||||
p.setFont(st::noContactsFont->f);
|
||||
p.setPen(st::noContactsColor->p);
|
||||
p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_contacts : lng_contacts_loading), style::al_center);
|
||||
p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_chats : lng_contacts_loading), style::al_center);
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (!hashtagResults.isEmpty()) {
|
||||
@@ -181,6 +187,18 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (_searchInPeer) {
|
||||
searchInPeerPaint(p, width());
|
||||
p.translate(0, st::dlgHeight);
|
||||
if (_state == FilteredState && searchResults.isEmpty()) {
|
||||
p.fillRect(0, 0, width(), st::searchedBarHeight, st::searchedBarBG->b);
|
||||
p.setFont(st::searchedBarFont->f);
|
||||
p.setPen(st::searchedBarColor->p);
|
||||
p.drawText(QRect(0, 0, width(), st::searchedBarHeight), lang(lng_dlg_search_for_messages), style::al_center);
|
||||
p.translate(0, st::searchedBarHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (_state == SearchedState || !searchResults.isEmpty()) {
|
||||
QString text = lng_search_found_results(lt_count, searchResults.isEmpty() ? 0 : searchedCount);
|
||||
p.fillRect(0, 0, width(), st::searchedBarHeight, st::searchedBarBG->b);
|
||||
@@ -252,6 +270,31 @@ void DialogsListWidget::peopleResultPaint(UserData *user, QPainter &p, int32 w,
|
||||
history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
}
|
||||
|
||||
void DialogsListWidget::searchInPeerPaint(QPainter &p, int32 w) const {
|
||||
QRect fullRect(0, 0, w, st::dlgHeight);
|
||||
p.fillRect(fullRect, st::dlgBG->b);
|
||||
|
||||
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, _searchInPeer->photo->pix(st::dlgPhotoSize));
|
||||
|
||||
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
|
||||
int32 namewidth = w - nameleft - st::dlgPaddingHor * 2 - st::btnCancelSearch.width;
|
||||
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
|
||||
|
||||
// draw chat icon
|
||||
if (_searchInPeer->chat) {
|
||||
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip);
|
||||
}
|
||||
|
||||
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height);
|
||||
p.setFont(st::dlgHistFont->f);
|
||||
p.setPen(st::dlgTextColor->p);
|
||||
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->m.elidedText(lang(lng_dlg_search_chat), Qt::ElideRight, tr.width()));
|
||||
|
||||
p.setPen(st::dlgNameColor->p);
|
||||
App::history(_searchInPeer->id)->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
}
|
||||
|
||||
void DialogsListWidget::activate() {
|
||||
}
|
||||
|
||||
@@ -274,7 +317,7 @@ void DialogsListWidget::onUpdateSelected(bool force) {
|
||||
if (newSel) {
|
||||
contactSel = false;
|
||||
} else {
|
||||
newSel = contactsNoDialogs.list.rowAtY(mouseY - otherStart, st::dlgHeight);
|
||||
newSel = 0;// contactsNoDialogs.list.rowAtY(mouseY - otherStart, st::dlgHeight);
|
||||
contactSel = true;
|
||||
}
|
||||
if (newSel != sel) {
|
||||
@@ -347,6 +390,7 @@ void DialogsListWidget::mousePressEvent(QMouseEvent *e) {
|
||||
|
||||
void DialogsListWidget::resizeEvent(QResizeEvent *e) {
|
||||
_addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2);
|
||||
_cancelSearchInPeer.move(width() - st::dlgPaddingHor - st::btnCancelSearch.width, (st::dlgHeight - st::btnCancelSearch.height) / 2);
|
||||
}
|
||||
|
||||
void DialogsListWidget::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) {
|
||||
@@ -397,9 +441,8 @@ void DialogsListWidget::removePeer(PeerData *peer) {
|
||||
contactsNoDialogs.addByName(App::history(peer->id));
|
||||
}
|
||||
}
|
||||
// contactsNoDialogs.del(peer);
|
||||
// contacts.del(peer);
|
||||
// App::deleteHistory(peer->id);
|
||||
|
||||
Local::removeSavedPeer(peer);
|
||||
|
||||
emit App::main()->dialogsUpdated();
|
||||
|
||||
@@ -440,7 +483,7 @@ void DialogsListWidget::dlgUpdated(History *history) {
|
||||
if (i != dialogs.list.rowByPeer.cend()) {
|
||||
update(0, i.value()->pos * st::dlgHeight, width(), st::dlgHeight);
|
||||
} else {
|
||||
i = contactsNoDialogs.list.rowByPeer.find(history->peer->id);
|
||||
i = contactsNoDialogs.list.rowByPeer.end();// find(history->peer->id);
|
||||
if (i != contactsNoDialogs.list.rowByPeer.cend()) {
|
||||
update(0, (dialogs.list.count + i.value()->pos) * st::dlgHeight, width(), st::dlgHeight);
|
||||
}
|
||||
@@ -489,6 +532,7 @@ void DialogsListWidget::leaveEvent(QEvent *e) {
|
||||
if (sel || filteredSel >= 0 || hashtagSel >= 0 || searchedSel >= 0 || peopleSel >= 0) {
|
||||
sel = 0;
|
||||
filteredSel = searchedSel = peopleSel = hashtagSel = -1;
|
||||
setCursor(style::cur_default);
|
||||
parentWidget()->update();
|
||||
}
|
||||
}
|
||||
@@ -538,7 +582,7 @@ void DialogsListWidget::onFilterUpdate(QString newFilter, bool force) {
|
||||
}
|
||||
if (newFilter != filter || force) {
|
||||
filter = newFilter;
|
||||
if (filter.isEmpty()) {
|
||||
if (!_searchInPeer && filter.isEmpty()) {
|
||||
_state = DefaultState;
|
||||
hashtagResults.clear();
|
||||
filterResults.clear();
|
||||
@@ -550,7 +594,7 @@ void DialogsListWidget::onFilterUpdate(QString newFilter, bool force) {
|
||||
|
||||
_state = FilteredState;
|
||||
filterResults.clear();
|
||||
if (!f.isEmpty()) {
|
||||
if (!_searchInPeer && !f.isEmpty()) {
|
||||
DialogsList *dialogsToFilter = 0, *contactsNoDialogsToFilter = 0;
|
||||
if (dialogs.list.count) {
|
||||
for (fi = fb; fi != fe; ++fi) {
|
||||
@@ -629,7 +673,7 @@ void DialogsListWidget::onFilterUpdate(QString newFilter, bool force) {
|
||||
}
|
||||
|
||||
void DialogsListWidget::onHashtagFilterUpdate(QStringRef newFilter) {
|
||||
if (newFilter.isEmpty() || newFilter.at(0) != '#') {
|
||||
if (newFilter.isEmpty() || newFilter.at(0) != '#' || _searchInPeer) {
|
||||
_hashtagFilter = QString();
|
||||
if (!hashtagResults.isEmpty()) {
|
||||
hashtagResults.clear();
|
||||
@@ -729,6 +773,16 @@ void DialogsListWidget::dialogsReceived(const QVector<MTPDialog> &added) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
void DialogsListWidget::addAllSavedPeers() {
|
||||
SavedPeersByTime &saved(cRefSavedPeersByTime());
|
||||
while (!saved.isEmpty()) {
|
||||
History *history = App::history(saved.last()->id);
|
||||
history->dialogs = dialogs.addToEnd(history);
|
||||
contactsNoDialogs.del(history->peer);
|
||||
saved.remove(saved.lastKey(), saved.last());
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsListWidget::searchReceived(const QVector<MTPMessage> &messages, bool fromStart, int32 fullCount) {
|
||||
if (fromStart) {
|
||||
clearSearchResults(false);
|
||||
@@ -768,7 +822,7 @@ void DialogsListWidget::contactsReceived(const QVector<MTPContact> &contacts) {
|
||||
App::self()->contact = 1;
|
||||
}
|
||||
}
|
||||
if (!sel && contactsNoDialogs.list.count) {
|
||||
if (!sel && contactsNoDialogs.list.count && false) {
|
||||
sel = contactsNoDialogs.list.begin;
|
||||
contactSel = true;
|
||||
}
|
||||
@@ -785,11 +839,11 @@ int32 DialogsListWidget::addNewContact(int32 uid, bool select) {
|
||||
if (i == dialogs.list.rowByPeer.cend()) {
|
||||
DialogRow *added = contactsNoDialogs.addByName(history);
|
||||
if (!added) return -1;
|
||||
if (select) {
|
||||
if (select && false) {
|
||||
sel = added;
|
||||
contactSel = true;
|
||||
}
|
||||
if (contactsNoDialogs.list.count == 1 && !dialogs.list.count) refresh();
|
||||
// if (contactsNoDialogs.list.count == 1 && !dialogs.list.count) refresh();
|
||||
return added ? ((dialogs.list.count + added->pos) * st::dlgHeight) : -1;
|
||||
}
|
||||
if (select) {
|
||||
@@ -802,7 +856,7 @@ int32 DialogsListWidget::addNewContact(int32 uid, bool select) {
|
||||
void DialogsListWidget::refresh(bool toTop) {
|
||||
int32 h = 0;
|
||||
if (_state == DefaultState) {
|
||||
h = (dialogs.list.count + contactsNoDialogs.list.count) * st::dlgHeight;
|
||||
h = (dialogs.list.count/* + contactsNoDialogs.list.count*/) * st::dlgHeight;
|
||||
if (h) {
|
||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||
} else {
|
||||
@@ -816,7 +870,7 @@ void DialogsListWidget::refresh(bool toTop) {
|
||||
} else {
|
||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||
if (_state == FilteredState) {
|
||||
h = searchedOffset() + (searchResults.count() * st::dlgHeight) + (searchResults.isEmpty() ? 0 : st::searchedBarHeight);
|
||||
h = searchedOffset() + (searchResults.count() * st::dlgHeight) + ((searchResults.isEmpty() && !_searchInPeer) ? 0 : st::searchedBarHeight);
|
||||
} else if (_state == SearchedState) {
|
||||
h = searchedOffset() + (searchResults.count() * st::dlgHeight) + st::searchedBarHeight;
|
||||
}
|
||||
@@ -837,6 +891,7 @@ void DialogsListWidget::setMouseSel(bool msel, bool toTop) {
|
||||
contactSel = !dialogs.list.count && contactsNoDialogs.list.count;
|
||||
} else if (_state == FilteredState || _state == SearchedState) { // don't select first elem in search
|
||||
filteredSel = peopleSel = searchedSel = hashtagSel = -1;
|
||||
setCursor(style::cur_default);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -864,9 +919,23 @@ bool DialogsListWidget::hasFilteredResults() const {
|
||||
return !filterResults.isEmpty() && hashtagResults.isEmpty();
|
||||
}
|
||||
|
||||
void DialogsListWidget::searchInPeer(PeerData *peer) {
|
||||
_searchInPeer = peer;
|
||||
if (_searchInPeer) {
|
||||
onHashtagFilterUpdate(QStringRef());
|
||||
_cancelSearchInPeer.show();
|
||||
} else {
|
||||
_cancelSearchInPeer.hide();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsListWidget::clearFilter() {
|
||||
if (_state == FilteredState || _state == SearchedState) {
|
||||
_state = DefaultState;
|
||||
if (_searchInPeer) {
|
||||
_state = FilteredState;
|
||||
} else {
|
||||
_state = DefaultState;
|
||||
}
|
||||
hashtagResults.clear();
|
||||
filterResults.clear();
|
||||
peopleResults.clear();
|
||||
@@ -879,6 +948,15 @@ void DialogsListWidget::clearFilter() {
|
||||
|
||||
void DialogsListWidget::addDialog(const MTPDdialog &dialog) {
|
||||
History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v);
|
||||
if (history->lastMsg) {
|
||||
SavedPeersByTime &saved(cRefSavedPeersByTime());
|
||||
while (!saved.isEmpty() && history->lastMsg->date < saved.lastKey()) {
|
||||
History *history = App::history(saved.last()->id);
|
||||
history->dialogs = dialogs.addToEnd(history);
|
||||
contactsNoDialogs.del(history->peer);
|
||||
saved.remove(saved.lastKey(), saved.last());
|
||||
}
|
||||
}
|
||||
History::DialogLinks links = dialogs.addToEnd(history);
|
||||
history->dialogs = links;
|
||||
contactsNoDialogs.del(history->peer);
|
||||
@@ -1388,6 +1466,7 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
|
||||
, _cancelSearch(this, st::btnCancelSearch)
|
||||
, scroll(this, st::dlgScroll)
|
||||
, list(&scroll, parent)
|
||||
, _searchInPeer(0)
|
||||
, _searchFull(false)
|
||||
, _peopleFull(false)
|
||||
{
|
||||
@@ -1399,6 +1478,7 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
|
||||
connect(&list, SIGNAL(searchResultChosen()), this, SLOT(onCancel()));
|
||||
connect(&list, SIGNAL(completeHashtag(QString)), this, SLOT(onCompleteHashtag(QString)));
|
||||
connect(&list, SIGNAL(refreshHashtags()), this, SLOT(onFilterCursorMoved()));
|
||||
connect(&list, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer()));
|
||||
connect(&scroll, SIGNAL(geometryChanged()), &list, SLOT(onParentGeometryChanged()));
|
||||
connect(&scroll, SIGNAL(scrolled()), &list, SLOT(onUpdateSelected()));
|
||||
connect(&scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
|
||||
@@ -1494,7 +1574,7 @@ bool DialogsWidget::animStep(float64 ms) {
|
||||
}
|
||||
|
||||
void DialogsWidget::onCancel() {
|
||||
if (!onCancelSearch() || !App::main()->selectingPeer()) {
|
||||
if (!onCancelSearch() || (!_searchInPeer && !App::main()->selectingPeer())) {
|
||||
emit cancelled();
|
||||
}
|
||||
}
|
||||
@@ -1598,10 +1678,10 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
||||
} else if (_searchQuery != q) {
|
||||
_searchQuery = q;
|
||||
_searchFull = false;
|
||||
_searchRequest = MTP::send(MTPmessages_Search(MTP_inputPeerEmpty(), MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, true), rpcFail(&DialogsWidget::searchFailed));
|
||||
_searchRequest = MTP::send(MTPmessages_Search(_searchInPeer ? _searchInPeer->input : MTP_inputPeerEmpty(), MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, true), rpcFail(&DialogsWidget::searchFailed));
|
||||
_searchQueries.insert(_searchRequest, _searchQuery);
|
||||
}
|
||||
if (q.size() >= MinUsernameLength) {
|
||||
if (!_searchInPeer && q.size() >= MinUsernameLength) {
|
||||
if (searchCache) {
|
||||
PeopleCache::const_iterator i = _peopleCache.constFind(q);
|
||||
if (i != _peopleCache.cend()) {
|
||||
@@ -1645,7 +1725,7 @@ void DialogsWidget::searchMessages(const QString &query) {
|
||||
|
||||
void DialogsWidget::onSearchMore(MsgId minMsgId) {
|
||||
if (!_searchRequest && !_searchFull) {
|
||||
_searchRequest = MTP::send(MTPmessages_Search(MTP_inputPeerEmpty(), MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(minMsgId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, !minMsgId), rpcFail(&DialogsWidget::searchFailed));
|
||||
_searchRequest = MTP::send(MTPmessages_Search(_searchInPeer ? _searchInPeer->input : MTP_inputPeerEmpty(), MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(minMsgId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, !minMsgId), rpcFail(&DialogsWidget::searchFailed));
|
||||
if (!minMsgId) {
|
||||
_searchQueries.insert(_searchRequest, _searchQuery);
|
||||
}
|
||||
@@ -1655,6 +1735,7 @@ void DialogsWidget::onSearchMore(MsgId minMsgId) {
|
||||
void DialogsWidget::loadDialogs() {
|
||||
if (dlgPreloading) return;
|
||||
if (dlgCount >= 0 && dlgOffset >= dlgCount) {
|
||||
list.addAllSavedPeers();
|
||||
cSetDialogsReceived(true);
|
||||
return;
|
||||
}
|
||||
@@ -1875,6 +1956,14 @@ void DialogsWidget::onFilterUpdate(bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::searchInPeer(PeerData *peer) {
|
||||
onCancelSearch();
|
||||
_searchInPeer = peer;
|
||||
list.searchInPeer(peer);
|
||||
onFilterUpdate(true);
|
||||
list.onFilterUpdate(_filter.text(), true);
|
||||
}
|
||||
|
||||
void DialogsWidget::onFilterCursorMoved(int from, int to) {
|
||||
if (to < 0) to = _filter.cursorPosition();
|
||||
QString t = _filter.text();
|
||||
@@ -2033,6 +2122,14 @@ void DialogsWidget::onNewGroup() {
|
||||
|
||||
bool DialogsWidget::onCancelSearch() {
|
||||
bool clearing = !_filter.text().isEmpty();
|
||||
if (_searchInPeer && !clearing) {
|
||||
if (!cWideMode()) {
|
||||
App::main()->showPeerHistory(_searchInPeer->id, ShowAtUnreadMsgId);
|
||||
}
|
||||
_searchInPeer = 0;
|
||||
list.searchInPeer(0);
|
||||
clearing = true;
|
||||
}
|
||||
list.clearFilter();
|
||||
_filter.clear();
|
||||
_filter.updatePlaceholder();
|
||||
@@ -2040,6 +2137,23 @@ bool DialogsWidget::onCancelSearch() {
|
||||
return clearing;
|
||||
}
|
||||
|
||||
void DialogsWidget::onCancelSearchInPeer() {
|
||||
if (_searchInPeer) {
|
||||
if (!cWideMode()) {
|
||||
App::main()->showPeerHistory(_searchInPeer->id, ShowAtUnreadMsgId);
|
||||
}
|
||||
_searchInPeer = 0;
|
||||
list.searchInPeer(0);
|
||||
}
|
||||
list.clearFilter();
|
||||
_filter.clear();
|
||||
_filter.updatePlaceholder();
|
||||
onFilterUpdate();
|
||||
if (cWideMode()) {
|
||||
emit cancelled();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::onDialogToTopFrom(int movedFrom) {
|
||||
if (scroll.scrollTop() > 0) {
|
||||
if (movedFrom > scroll.scrollTop()) {
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
DialogsListWidget(QWidget *parent, MainWidget *main);
|
||||
|
||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||
void addAllSavedPeers();
|
||||
void searchReceived(const QVector<MTPMessage> &messages, bool fromStart, int32 fullCount);
|
||||
void peopleReceived(const QString &query, const QVector<MTPContactFound> &people);
|
||||
void showMore(int32 pixels);
|
||||
@@ -48,6 +49,7 @@ public:
|
||||
void leaveEvent(QEvent *e);
|
||||
|
||||
void peopleResultPaint(UserData *user, QPainter &p, int32 w, bool act, bool sel) const;
|
||||
void searchInPeerPaint(QPainter &p, int32 w) const;
|
||||
|
||||
void selectSkip(int32 direction);
|
||||
void selectSkipPage(int32 pixels, int32 direction);
|
||||
@@ -93,6 +95,8 @@ public:
|
||||
State state() const;
|
||||
bool hasFilteredResults() const;
|
||||
|
||||
void searchInPeer(PeerData *peer);
|
||||
|
||||
void onFilterUpdate(QString newFilter, bool force = false);
|
||||
void onHashtagFilterUpdate(QStringRef newFilter);
|
||||
void itemRemoved(HistoryItem *item);
|
||||
@@ -117,6 +121,7 @@ signals:
|
||||
void dialogToTopFrom(int movedFrom);
|
||||
void searchMessages();
|
||||
void searchResultChosen();
|
||||
void cancelSearchInPeer();
|
||||
void completeHashtag(QString tag);
|
||||
void refreshHashtags();
|
||||
|
||||
@@ -156,9 +161,12 @@ private:
|
||||
void paintDialog(QPainter &p, DialogRow *dialog);
|
||||
|
||||
LinkButton _addContactLnk;
|
||||
IconedButton _cancelSearchInPeer;
|
||||
|
||||
bool _overDelete;
|
||||
|
||||
PeerData *_searchInPeer;
|
||||
|
||||
};
|
||||
|
||||
class DialogsWidget : public QWidget, public Animated, public RPCSender {
|
||||
@@ -183,6 +191,8 @@ public:
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void searchInPeer(PeerData *peer);
|
||||
|
||||
void loadDialogs();
|
||||
void createDialogAtTop(History *history, int32 unreadCount);
|
||||
void dlgUpdated(DialogRow *row);
|
||||
@@ -226,6 +236,7 @@ public slots:
|
||||
void onAddContact();
|
||||
void onNewGroup();
|
||||
bool onCancelSearch();
|
||||
void onCancelSearchInPeer();
|
||||
|
||||
void onFilterCursorMoved(int from = -1, int to = -1);
|
||||
void onCompleteHashtag(QString tag);
|
||||
@@ -262,6 +273,8 @@ private:
|
||||
anim::ivalue a_coord, a_bgCoord;
|
||||
anim::fvalue a_alpha, a_bgAlpha;
|
||||
|
||||
PeerData *_searchInPeer;
|
||||
|
||||
QTimer _searchTimer;
|
||||
QString _searchQuery, _peopleQuery;
|
||||
bool _searchFull, _peopleFull;
|
||||
|
||||
@@ -273,6 +273,7 @@ void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
|
||||
audio->uploadOffset = audio->size;
|
||||
}
|
||||
}
|
||||
emit audioProgress(k.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,6 +774,8 @@ void FlatTextarea::keyPressEvent(QKeyEvent *e) {
|
||||
} else {
|
||||
emit tabbed();
|
||||
}
|
||||
} else if (e->key() == Qt::Key_Search || e == QKeySequence::Find) {
|
||||
e->ignore();
|
||||
} else {
|
||||
QTextCursor tc(textCursor());
|
||||
if (enter && ctrl) {
|
||||
|
||||
@@ -29,6 +29,9 @@ struct StorageImageLocation {
|
||||
}
|
||||
StorageImageLocation(int32 width, int32 height, const MTPDfileLocation &location) : width(width), height(height), dc(location.vdc_id.v), volume(location.vvolume_id.v), local(location.vlocal_id.v), secret(location.vsecret.v) {
|
||||
}
|
||||
bool isNull() const {
|
||||
return !dc;
|
||||
}
|
||||
int32 width, height;
|
||||
int32 dc;
|
||||
uint64 volume;
|
||||
@@ -36,6 +39,13 @@ struct StorageImageLocation {
|
||||
uint64 secret;
|
||||
};
|
||||
|
||||
inline bool operator==(const StorageImageLocation &a, const StorageImageLocation &b) {
|
||||
return !memcmp(&a, &b, sizeof(StorageImageLocation));
|
||||
}
|
||||
inline bool operator!=(const StorageImageLocation &a, const StorageImageLocation &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
class Image {
|
||||
public:
|
||||
|
||||
@@ -144,6 +154,10 @@ inline StorageKey storageKey(int32 dc, const uint64 &volume, int32 local) {
|
||||
inline StorageKey storageKey(const MTPDfileLocation &location) {
|
||||
return storageKey(location.vdc_id.v, location.vvolume_id.v, location.vlocal_id.v);
|
||||
}
|
||||
inline StorageKey storageKey(const StorageImageLocation &location) {
|
||||
return storageKey(location.dc, location.volume, location.local);
|
||||
}
|
||||
|
||||
enum StorageFileType {
|
||||
StorageFileUnknown = 0xaa963b05, // mtpc_storage_fileUnknown
|
||||
StorageFileJpeg = 0x7efe0e, // mtpc_storage_fileJpeg
|
||||
|
||||
@@ -167,7 +167,7 @@ void DialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const {
|
||||
if (!last) {
|
||||
p.setFont(st::dlgHistFont->f);
|
||||
p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p);
|
||||
if (history->typing.isEmpty()) {
|
||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
||||
p.drawText(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgFont->ascent + st::dlgSep, lang(lng_empty_history));
|
||||
} else {
|
||||
history->typingText.drawElided(p, nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth);
|
||||
@@ -223,7 +223,7 @@ void DialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const {
|
||||
p.setPen((act ? st::dlgActiveUnreadColor : st::dlgUnreadColor)->p);
|
||||
p.drawText(unreadRectLeft + st::dlgUnreadPaddingHor, unreadRectTop + st::dlgUnreadPaddingVer + st::dlgUnreadFont->ascent, unreadStr);
|
||||
}
|
||||
if (history->typing.isEmpty()) {
|
||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
||||
last->drawInDialog(p, QRect(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, lastWidth, st::dlgFont->height), act, history->textCachedFor, history->lastItemTextCache);
|
||||
} else {
|
||||
p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p);
|
||||
@@ -319,7 +319,6 @@ History::History(const PeerId &peerId) : width(0), height(0)
|
||||
, lastItemTextCache(st::dlgRichMinWidth)
|
||||
, posInDialogs(0)
|
||||
, typingText(st::dlgRichMinWidth)
|
||||
, myTyping(0)
|
||||
{
|
||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
||||
_overviewCount[i] = -1; // not loaded yet
|
||||
@@ -347,6 +346,14 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
for (SendActionUsers::iterator i = sendActions.begin(), e = sendActions.end(); i != e;) {
|
||||
if (ms >= i.value().until) {
|
||||
i = sendActions.erase(i);
|
||||
changed = true;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
QString newTypingStr;
|
||||
int32 cnt = typing.size();
|
||||
@@ -356,6 +363,17 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
|
||||
newTypingStr = lng_users_typing(lt_user, typing.begin().key()->firstName, lt_second_user, (typing.end() - 1).key()->firstName);
|
||||
} else if (cnt) {
|
||||
newTypingStr = peer->chat ? lng_user_typing(lt_user, typing.begin().key()->firstName) : lang(lng_typing);
|
||||
} else if (!sendActions.isEmpty()) {
|
||||
switch (sendActions.begin().value().type) {
|
||||
case SendActionRecordVideo: newTypingStr = peer->chat ? lng_user_action_record_video(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_record_video); break;
|
||||
case SendActionUploadVideo: newTypingStr = peer->chat ? lng_user_action_upload_video(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_video); break;
|
||||
case SendActionRecordAudio: newTypingStr = peer->chat ? lng_user_action_record_audio(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_record_audio); break;
|
||||
case SendActionUploadAudio: newTypingStr = peer->chat ? lng_user_action_upload_audio(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_audio); break;
|
||||
case SendActionUploadPhoto: newTypingStr = peer->chat ? lng_user_action_upload_photo(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_photo); break;
|
||||
case SendActionUploadFile: newTypingStr = peer->chat ? lng_user_action_upload_file(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_file); break;
|
||||
case SendActionChooseLocation: newTypingStr = peer->chat ? lng_user_action_geo_location(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_geo_location); break;
|
||||
case SendActionChooseContact: newTypingStr = peer->chat ? lng_user_action_choose_contact(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_choose_contact); break;
|
||||
}
|
||||
}
|
||||
if (!newTypingStr.isEmpty()) {
|
||||
newTypingStr += qsl("...");
|
||||
@@ -506,9 +524,25 @@ void Histories::clear() {
|
||||
Parent::clear();
|
||||
}
|
||||
|
||||
void Histories::regTyping(History *history, UserData *user) {
|
||||
void Histories::regSendAction(History *history, UserData *user, const MTPSendMessageAction &action) {
|
||||
if (action.type() == mtpc_sendMessageCancelAction) {
|
||||
history->unregTyping(user);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 ms = getms(true);
|
||||
history->typing[user] = ms + 6000;
|
||||
switch (action.type()) {
|
||||
case mtpc_sendMessageTypingAction: history->typing[user] = ms + 6000; break;
|
||||
case mtpc_sendMessageRecordVideoAction: history->sendActions.insert(user, SendAction(SendActionRecordVideo, ms + 6000)); break;
|
||||
case mtpc_sendMessageUploadVideoAction: history->sendActions.insert(user, SendAction(SendActionUploadVideo, ms + 6000, action.c_sendMessageUploadVideoAction().vprogress.v)); break;
|
||||
case mtpc_sendMessageRecordAudioAction: history->sendActions.insert(user, SendAction(SendActionRecordAudio, ms + 6000)); break;
|
||||
case mtpc_sendMessageUploadAudioAction: history->sendActions.insert(user, SendAction(SendActionUploadAudio, ms + 6000, action.c_sendMessageUploadAudioAction().vprogress.v)); break;
|
||||
case mtpc_sendMessageUploadPhotoAction: history->sendActions.insert(user, SendAction(SendActionUploadPhoto, ms + 6000, action.c_sendMessageUploadPhotoAction().vprogress.v)); break;
|
||||
case mtpc_sendMessageUploadDocumentAction: history->sendActions.insert(user, SendAction(SendActionUploadFile, ms + 6000, action.c_sendMessageUploadDocumentAction().vprogress.v)); break;
|
||||
case mtpc_sendMessageGeoLocationAction: history->sendActions.insert(user, SendAction(SendActionChooseLocation, ms + 6000)); break;
|
||||
case mtpc_sendMessageChooseContactAction: history->sendActions.insert(user, SendAction(SendActionChooseContact, ms + 6000)); break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
user->madeAction();
|
||||
|
||||
@@ -530,7 +564,7 @@ bool Histories::animStep(float64) {
|
||||
App::main()->dlgUpdated(i.key());
|
||||
App::main()->topBar()->update();
|
||||
}
|
||||
if (i.key()->typing.isEmpty()) {
|
||||
if (i.key()->typing.isEmpty() && i.key()->sendActions.isEmpty()) {
|
||||
i = typing.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
@@ -579,7 +613,7 @@ HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) {
|
||||
if (!h.value()->loadedAtBottom()) {
|
||||
HistoryItem *item = h.value()->addToHistory(msg);
|
||||
if (item) {
|
||||
h.value()->lastMsg = item;
|
||||
h.value()->setLastMessage(item);
|
||||
if (msgState > 0) {
|
||||
h.value()->newItemAdded(item);
|
||||
}
|
||||
@@ -874,7 +908,8 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||
}
|
||||
}
|
||||
to->push_back(adding);
|
||||
lastMsg = adding;
|
||||
setLastMessage(adding);
|
||||
|
||||
adding->y = to->height;
|
||||
if (width) {
|
||||
int32 dh = adding->resize(width);
|
||||
@@ -885,6 +920,7 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||
if (newMsg) {
|
||||
newItemAdded(adding);
|
||||
}
|
||||
|
||||
HistoryMedia *media = adding->getMedia(true);
|
||||
if (media) {
|
||||
HistoryMediaType mt = media->type();
|
||||
@@ -943,11 +979,22 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||
}
|
||||
|
||||
void History::unregTyping(UserData *from) {
|
||||
bool update = false;
|
||||
uint64 updateAtMs = 0;
|
||||
TypingUsers::iterator i = typing.find(from);
|
||||
if (i != typing.end()) {
|
||||
uint64 ms = getms(true);
|
||||
i.value() = ms;
|
||||
updateTyping(ms, 0, true);
|
||||
updateAtMs = getms(true);
|
||||
i.value() = updateAtMs;
|
||||
update = true;
|
||||
}
|
||||
SendActionUsers::iterator j = sendActions.find(from);
|
||||
if (j != sendActions.end()) {
|
||||
if (!updateAtMs) updateAtMs = getms(true);
|
||||
j.value().until = updateAtMs;
|
||||
update = true;
|
||||
}
|
||||
if (updateAtMs) {
|
||||
updateTyping(updateAtMs, 0, true);
|
||||
App::main()->topBar()->update();
|
||||
}
|
||||
}
|
||||
@@ -1369,14 +1416,24 @@ void History::getReadyFor(MsgId msgId) {
|
||||
}
|
||||
}
|
||||
|
||||
void History::setLastMessage(HistoryItem *msg) {
|
||||
if (msg) {
|
||||
if (!lastMsg) Local::removeSavedPeer(peer);
|
||||
lastMsg = msg;
|
||||
lastMsgDate = msg->date;
|
||||
} else {
|
||||
lastMsg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void History::fixLastMessage(bool wasAtBottom) {
|
||||
if (wasAtBottom && isEmpty()) {
|
||||
wasAtBottom = false;
|
||||
}
|
||||
if (wasAtBottom) {
|
||||
lastMsg = back()->back();
|
||||
setLastMessage(back()->back());
|
||||
} else {
|
||||
lastMsg = 0;
|
||||
setLastMessage(0);
|
||||
if (App::main()) {
|
||||
App::main()->checkPeerHistory(peer);
|
||||
}
|
||||
@@ -1436,9 +1493,16 @@ void History::clear(bool leaveItems) {
|
||||
if (showFrom) {
|
||||
showFrom = 0;
|
||||
}
|
||||
if (!leaveItems) {
|
||||
setLastMessage(0);
|
||||
}
|
||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
||||
if (!_overview[i].isEmpty() || !_overviewIds[i].isEmpty()) {
|
||||
if (_overviewCount[i] == 0) _overviewCount[i] = _overview[i].size();
|
||||
if (leaveItems) {
|
||||
if (_overviewCount[i] == 0) _overviewCount[i] = _overview[i].size();
|
||||
} else {
|
||||
_overviewCount[i] = -1; // not loaded yet
|
||||
}
|
||||
_overview[i].clear();
|
||||
_overviewIds[i].clear();
|
||||
if (App::wnd() && !App::quiting()) App::wnd()->mediaOverviewUpdated(peer, MediaOverviewType(i));
|
||||
@@ -1456,7 +1520,6 @@ void History::clear(bool leaveItems) {
|
||||
lastKeyboardInited = false;
|
||||
} else {
|
||||
setUnreadCount(0);
|
||||
lastMsg = 0;
|
||||
}
|
||||
height = 0;
|
||||
oldLoaded = false;
|
||||
|
||||
@@ -41,7 +41,7 @@ struct Histories : public QHash<PeerId, History*>, public Animated {
|
||||
Histories() : unreadFull(0), unreadMuted(0) {
|
||||
}
|
||||
|
||||
void regTyping(History *history, UserData *user);
|
||||
void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action);
|
||||
bool animStep(float64 ms);
|
||||
|
||||
void clear();
|
||||
@@ -134,6 +134,25 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
||||
return MTPMessagesFilter();
|
||||
}
|
||||
|
||||
enum SendActionType {
|
||||
SendActionTyping,
|
||||
SendActionRecordVideo,
|
||||
SendActionUploadVideo,
|
||||
SendActionRecordAudio,
|
||||
SendActionUploadAudio,
|
||||
SendActionUploadPhoto,
|
||||
SendActionUploadFile,
|
||||
SendActionChooseLocation,
|
||||
SendActionChooseContact,
|
||||
};
|
||||
struct SendAction {
|
||||
SendAction(SendActionType type, uint64 until, int32 progress = 0) : type(type), until(until), progress(progress) {
|
||||
}
|
||||
SendActionType type;
|
||||
uint64 until;
|
||||
int32 progress;
|
||||
};
|
||||
|
||||
class HistoryMedia;
|
||||
class HistoryMessage;
|
||||
class HistoryUnreadBar;
|
||||
@@ -185,6 +204,7 @@ struct History : public QList<HistoryBlock*> {
|
||||
bool isReadyFor(MsgId msgId, bool check = false) const; // has messages for showing history at msgId
|
||||
void getReadyFor(MsgId msgId);
|
||||
|
||||
void setLastMessage(HistoryItem *msg);
|
||||
void fixLastMessage(bool wasAtBottom);
|
||||
|
||||
MsgId minMsgId() const;
|
||||
@@ -199,6 +219,7 @@ struct History : public QList<HistoryBlock*> {
|
||||
PeerData *peer;
|
||||
bool oldLoaded, newLoaded;
|
||||
HistoryItem *lastMsg;
|
||||
QDateTime lastMsgDate;
|
||||
|
||||
typedef QList<HistoryItem*> NotifyQueue;
|
||||
NotifyQueue notifies;
|
||||
@@ -273,11 +294,13 @@ struct History : public QList<HistoryBlock*> {
|
||||
|
||||
typedef QMap<UserData*, uint64> TypingUsers;
|
||||
TypingUsers typing;
|
||||
typedef QMap<UserData*, SendAction> SendActionUsers;
|
||||
SendActionUsers sendActions;
|
||||
QString typingStr;
|
||||
Text typingText;
|
||||
uint32 typingFrame;
|
||||
bool updateTyping(uint64 ms = 0, uint32 dots = 0, bool force = false);
|
||||
uint64 myTyping;
|
||||
QMap<SendActionType, uint64> mySendActions;
|
||||
|
||||
typedef QList<MsgId> MediaOverview;
|
||||
typedef QMap<MsgId, NullType> MediaOverviewIds;
|
||||
@@ -425,11 +448,11 @@ struct DialogsList {
|
||||
|
||||
DialogRow *row = addToEnd(history), *change = row;
|
||||
const QString &peerName(history->peer->name);
|
||||
while (change->prev && change->prev->history->peer->name > peerName) {
|
||||
while (change->prev && change->prev->history->peer->name.compare(peerName, Qt::CaseInsensitive) > 0) {
|
||||
change = change->prev;
|
||||
}
|
||||
if (!insertBefore(row, change)) {
|
||||
while (change->next != end && change->next->history->peer->name < peerName) {
|
||||
while (change->next != end && change->next->history->peer->name.compare(peerName, Qt::CaseInsensitive) < 0) {
|
||||
change = change->next;
|
||||
}
|
||||
insertAfter(row, change);
|
||||
|
||||
@@ -75,7 +75,9 @@ HistoryList::HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, Histo
|
||||
|
||||
_trippleClickTimer.setSingleShot(true);
|
||||
|
||||
if (botInfo && !botInfo->inited) App::api()->requestFullPeer(hist->peer);
|
||||
if (botInfo && !botInfo->inited) {
|
||||
App::api()->requestFullPeer(hist->peer);
|
||||
}
|
||||
|
||||
setMouseTracking(true);
|
||||
}
|
||||
@@ -2200,7 +2202,9 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
, _toHistoryEnd(this, st::historyToEnd)
|
||||
, _attachMention(this)
|
||||
, _send(this, lang(lng_send_button), st::btnSend)
|
||||
, _unblock(this, lang(lng_unblock_button), st::btnUnblock)
|
||||
, _botStart(this, lang(lng_bot_start), st::btnSend)
|
||||
, _unblockRequest(0)
|
||||
, _attachDocument(this, st::btnAttachDocument)
|
||||
, _attachPhoto(this, st::btnAttachPhoto)
|
||||
, _attachEmoji(this, st::btnAttachEmoji)
|
||||
@@ -2233,7 +2237,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
, _titlePeerTextWidth(0)
|
||||
, _showAnim(animFunc(this, &HistoryWidget::showStep))
|
||||
, _scrollDelta(0)
|
||||
, _typingRequest(0)
|
||||
, _saveDraftStart(0)
|
||||
, _saveDraftText(false) {
|
||||
_scroll.setFocusPolicy(Qt::NoFocus);
|
||||
@@ -2244,6 +2247,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
connect(&_toHistoryEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd()));
|
||||
connect(&_replyForwardPreviewCancel, SIGNAL(clicked()), this, SLOT(onReplyForwardPreviewCancel()));
|
||||
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||
connect(&_unblock, SIGNAL(clicked()), this, SLOT(onUnblock()));
|
||||
connect(&_botStart, SIGNAL(clicked()), this, SLOT(onBotStart()));
|
||||
connect(&_attachDocument, SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
|
||||
connect(&_attachPhoto, SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
|
||||
@@ -2262,7 +2266,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
connect(&_emojiPan, SIGNAL(emojiSelected(EmojiPtr)), &_field, SLOT(onEmojiInsert(EmojiPtr)));
|
||||
connect(&_emojiPan, SIGNAL(stickerSelected(DocumentData*)), this, SLOT(onStickerSend(DocumentData*)));
|
||||
connect(&_emojiPan, SIGNAL(updateStickers()), this, SLOT(updateStickers()));
|
||||
connect(&_typingStopTimer, SIGNAL(timeout()), this, SLOT(cancelTyping()));
|
||||
connect(&_sendActionStopTimer, SIGNAL(timeout()), this, SLOT(onCancelSendAction()));
|
||||
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreviewTimeout()));
|
||||
if (audioCapture()) {
|
||||
connect(audioCapture(), SIGNAL(onError()), this, SLOT(onRecordError()));
|
||||
@@ -2272,7 +2276,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
|
||||
_scrollTimer.setSingleShot(false);
|
||||
|
||||
_typingStopTimer.setSingleShot(true);
|
||||
_sendActionStopTimer.setSingleShot(true);
|
||||
|
||||
_animActiveTimer.setSingleShot(false);
|
||||
connect(&_animActiveTimer, SIGNAL(timeout()), this, SLOT(onAnimActiveStep()));
|
||||
@@ -2306,6 +2310,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
_field.hide();
|
||||
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _send.height() - 2 * st::sendPadding);
|
||||
_send.hide();
|
||||
_unblock.hide();
|
||||
_botStart.hide();
|
||||
|
||||
_attachDocument.hide();
|
||||
@@ -2350,7 +2355,7 @@ void HistoryWidget::onMentionHashtagOrBotCommandInsert(QString str) {
|
||||
}
|
||||
|
||||
void HistoryWidget::onTextChange() {
|
||||
updateTyping();
|
||||
updateSendAction(_history, SendActionTyping);
|
||||
|
||||
if (cHasAudioCapture()) {
|
||||
if (_field.getLastText().isEmpty() && !App::main()->hasForwardingItems()) {
|
||||
@@ -2411,22 +2416,55 @@ void HistoryWidget::writeDraft(MsgId *replyTo, const QString *text, const Messag
|
||||
if (save) Local::writeDraftPositions(_history->peer->id, cursor ? (*cursor) : MessageCursor(_field));
|
||||
}
|
||||
|
||||
void HistoryWidget::cancelTyping() {
|
||||
if (_typingRequest) {
|
||||
MTP::cancel(_typingRequest);
|
||||
_typingRequest = 0;
|
||||
void HistoryWidget::cancelSendAction(History *history, SendActionType type) {
|
||||
QMap<QPair<History*, SendActionType>, mtpRequestId>::iterator i = _sendActionRequests.find(qMakePair(history, type));
|
||||
if (i != _sendActionRequests.cend()) {
|
||||
MTP::cancel(i.value());
|
||||
_sendActionRequests.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::updateTyping(bool typing) {
|
||||
uint64 ms = getms(true) + 10000;
|
||||
if (_synthedTextUpdate || !_history || (typing && (_history->myTyping + 5000 > ms)) || (!typing && (_history->myTyping + 5000 <= ms))) return;
|
||||
void HistoryWidget::onCancelSendAction() {
|
||||
cancelSendAction(_history, SendActionTyping);
|
||||
}
|
||||
|
||||
_history->myTyping = typing ? ms : 0;
|
||||
cancelTyping();
|
||||
if (typing) {
|
||||
_typingRequest = MTP::send(MTPmessages_SetTyping(_peer->input, typing ? MTP_sendMessageTypingAction() : MTP_sendMessageCancelAction()), rpcDone(&HistoryWidget::typingDone));
|
||||
_typingStopTimer.start(5000);
|
||||
void HistoryWidget::updateSendAction(History *history, SendActionType type, int32 progress) {
|
||||
if (!history) return;
|
||||
if (type == SendActionTyping && _synthedTextUpdate) return;
|
||||
|
||||
bool doing = (progress >= 0);
|
||||
|
||||
uint64 ms = getms(true) + 10000;
|
||||
QMap<SendActionType, uint64>::iterator i = history->mySendActions.find(type);
|
||||
if (doing && i != history->mySendActions.cend() && i.value() + 5000 > ms) return;
|
||||
if (!doing && (i == history->mySendActions.cend() || i.value() + 5000 <= ms)) return;
|
||||
|
||||
if (doing) {
|
||||
if (i == history->mySendActions.cend()) {
|
||||
history->mySendActions.insert(type, ms);
|
||||
} else {
|
||||
i.value() = ms;
|
||||
}
|
||||
} else if (i != history->mySendActions.cend()) {
|
||||
history->mySendActions.erase(i);
|
||||
}
|
||||
|
||||
cancelSendAction(history, type);
|
||||
if (doing) {
|
||||
MTPsendMessageAction action;
|
||||
switch (type) {
|
||||
case SendActionTyping: action = MTP_sendMessageTypingAction(); break;
|
||||
case SendActionRecordVideo: action = MTP_sendMessageRecordVideoAction(); break;
|
||||
case SendActionUploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break;
|
||||
case SendActionRecordAudio: action = MTP_sendMessageRecordAudioAction(); break;
|
||||
case SendActionUploadAudio: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break;
|
||||
case SendActionUploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break;
|
||||
case SendActionUploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
|
||||
case SendActionChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
|
||||
case SendActionChooseContact: action = MTP_sendMessageChooseContactAction(); break;
|
||||
}
|
||||
_sendActionRequests.insert(qMakePair(history, type), MTP::send(MTPmessages_SetTyping(history->peer->input, action), rpcDone(&HistoryWidget::sendActionDone)));
|
||||
if (type == SendActionTyping) _sendActionStopTimer.start(5000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2438,16 +2476,19 @@ void HistoryWidget::stickersInstalled(uint64 setId) {
|
||||
_emojiPan.stickersInstalled(setId);
|
||||
}
|
||||
|
||||
void HistoryWidget::typingDone(const MTPBool &result, mtpRequestId req) {
|
||||
if (_typingRequest == req) {
|
||||
_typingRequest = 0;
|
||||
void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) {
|
||||
for (QMap<QPair<History*, SendActionType>, mtpRequestId>::iterator i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) {
|
||||
if (i.value() == req) {
|
||||
_sendActionRequests.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::activate() {
|
||||
if (_history) updateListSize(0, true);
|
||||
if (_list) {
|
||||
if (_selCount || (_list && _list->wasSelectedText()) || _recording || isBotStart()) {
|
||||
if (_selCount || (_list && _list->wasSelectedText()) || _recording || isBotStart() || isBlocked()) {
|
||||
_list->setFocus();
|
||||
} else {
|
||||
_field.setFocus();
|
||||
@@ -2480,6 +2521,7 @@ void HistoryWidget::onRecordUpdate(qint16 level, qint32 samples) {
|
||||
stopRecording(_peer && samples > 0 && _inField);
|
||||
}
|
||||
updateField();
|
||||
updateSendAction(_history, SendActionRecordAudio);
|
||||
}
|
||||
|
||||
void HistoryWidget::updateStickers() {
|
||||
@@ -2688,7 +2730,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
|
||||
update();
|
||||
return;
|
||||
}
|
||||
updateTyping(false);
|
||||
if (_history->mySendActions.contains(SendActionTyping)) updateSendAction(_history, SendActionTyping, -1);
|
||||
}
|
||||
|
||||
stopGif();
|
||||
@@ -2740,6 +2782,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
|
||||
}
|
||||
|
||||
_peer = peerId ? App::peer(peerId) : 0;
|
||||
_unblockRequest = 0;
|
||||
|
||||
_titlePeerText = QString();
|
||||
_titlePeerTextWidth = 0;
|
||||
@@ -2854,6 +2897,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
_scroll.hide();
|
||||
_kbScroll.hide();
|
||||
_send.hide();
|
||||
_unblock.hide();
|
||||
_botStart.hide();
|
||||
_attachMention.hide();
|
||||
_field.hide();
|
||||
@@ -2876,9 +2920,27 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
} else {
|
||||
_scroll.show();
|
||||
}
|
||||
if (!_peer->chat || !_peer->asChat()->forbidden) {
|
||||
if ((_peer->chat && !_peer->asChat()->forbidden && !_peer->asChat()->left) || (!_peer->chat && _peer->asUser()->access != UserNoAccess)) {
|
||||
checkMentionDropdown();
|
||||
if (isBotStart()) {
|
||||
if (isBlocked()) {
|
||||
_botStart.hide();
|
||||
if (_unblock.isHidden()) {
|
||||
_unblock.clearState();
|
||||
_unblock.show();
|
||||
_kbShown = false;
|
||||
}
|
||||
_send.hide();
|
||||
_field.hide();
|
||||
_attachEmoji.hide();
|
||||
_kbShow.hide();
|
||||
_kbHide.hide();
|
||||
_cmdStart.hide();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
_kbScroll.hide();
|
||||
_replyForwardPreviewCancel.hide();
|
||||
} else if (isBotStart()) {
|
||||
_unblock.hide();
|
||||
if (_botStart.isHidden()) {
|
||||
_botStart.clearState();
|
||||
_botStart.show();
|
||||
@@ -2895,6 +2957,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
_kbScroll.hide();
|
||||
_replyForwardPreviewCancel.hide();
|
||||
} else {
|
||||
_unblock.hide();
|
||||
_botStart.hide();
|
||||
if (cHasAudioCapture() && _field.getLastText().isEmpty() && !App::main()->hasForwardingItems()) {
|
||||
_send.hide();
|
||||
@@ -2971,6 +3034,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
} else {
|
||||
_attachMention.hide();
|
||||
_send.hide();
|
||||
_unblock.hide();
|
||||
_botStart.hide();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
@@ -3285,6 +3349,29 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||
if (!_keyboard.hasMarkup() && _keyboard.forceReply() && !_kbReplyTo) onKbToggle();
|
||||
}
|
||||
|
||||
void HistoryWidget::onUnblock() {
|
||||
if (_unblockRequest) return;
|
||||
if (!_peer || _peer->chat || _peer->asUser()->blocked != UserIsBlocked) {
|
||||
updateControlsVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
_unblockRequest = MTP::send(MTPcontacts_Unblock(_peer->asUser()->inputUser), rpcDone(&HistoryWidget::unblockDone, _peer), rpcFail(&HistoryWidget::unblockFail));
|
||||
}
|
||||
|
||||
void HistoryWidget::unblockDone(PeerData *peer, const MTPBool &result) {
|
||||
if (peer->chat) return;
|
||||
_unblockRequest = 0;
|
||||
peer->asUser()->blocked = UserIsNotBlocked;
|
||||
emit App::main()->peerUpdated(peer);
|
||||
}
|
||||
|
||||
bool HistoryWidget::unblockFail(const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
// _unblockRequest = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void HistoryWidget::onBotStart() {
|
||||
if (!_peer || _peer->chat || !_peer->asUser()->botInfo) {
|
||||
updateControlsVisibility();
|
||||
@@ -3338,7 +3425,7 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
|
||||
flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
|
||||
}
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup));
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup, MTPnullEntities));
|
||||
h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, h->sendRequestId);
|
||||
|
||||
App::historyRegRandom(randomId, newId);
|
||||
@@ -3382,6 +3469,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
|
||||
_field.hide();
|
||||
_replyForwardPreviewCancel.hide();
|
||||
_send.hide();
|
||||
_unblock.hide();
|
||||
_botStart.hide();
|
||||
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
|
||||
a_alpha = anim::fvalue(0, 1);
|
||||
@@ -3434,7 +3522,7 @@ void HistoryWidget::animStop() {
|
||||
bool HistoryWidget::recordStep(float64 ms) {
|
||||
float64 dt = ms / st::btnSend.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1 || !_send.isHidden() || isBotStart()) {
|
||||
if (dt >= 1 || !_send.isHidden() || isBotStart() || isBlocked()) {
|
||||
res = false;
|
||||
a_recordOver.finish();
|
||||
a_recordDown.finish();
|
||||
@@ -3602,6 +3690,8 @@ void HistoryWidget::stopRecording(bool send) {
|
||||
|
||||
_recording = false;
|
||||
_recordingSamples = 0;
|
||||
updateSendAction(_history, SendActionRecordAudio, -1);
|
||||
|
||||
updateControlsVisibility();
|
||||
activate();
|
||||
|
||||
@@ -3749,10 +3839,14 @@ bool HistoryWidget::isBotStart() const {
|
||||
return !_peer->asUser()->botInfo->startToken.isEmpty() || (_history->isEmpty() && !_history->lastMsg);
|
||||
}
|
||||
|
||||
bool HistoryWidget::isBlocked() const {
|
||||
return _peer && !_peer->chat && _peer->asUser()->blocked == UserIsBlocked;
|
||||
}
|
||||
|
||||
bool HistoryWidget::updateCmdStartShown() {
|
||||
bool cmdStartShown = false;
|
||||
if (_history && _peer && ((_peer->chat && _peer->asChat()->botStatus > 0) || (!_peer->chat && _peer->asUser()->botInfo))) {
|
||||
if (!isBotStart() && !_keyboard.hasMarkup() && !_keyboard.forceReply()) {
|
||||
if (!isBotStart() && !isBlocked() && !_keyboard.hasMarkup() && !_keyboard.forceReply()) {
|
||||
if (_field.getLastText().isEmpty()) {
|
||||
cmdStartShown = true;
|
||||
}
|
||||
@@ -3922,7 +4016,7 @@ void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth)
|
||||
decreaseWidth += increaseLeft;
|
||||
QRect rectForName(st::topBarForwardPadding.left() + increaseLeft, st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height);
|
||||
p.setFont(st::dlgHistFont->f);
|
||||
if (_history->typing.isEmpty()) {
|
||||
if (_history->typing.isEmpty() && _history->sendActions.isEmpty()) {
|
||||
p.setPen(st::titleStatusColor->p);
|
||||
p.drawText(rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dlgHistFont->height + st::dlgHistFont->ascent, _titlePeerText);
|
||||
} else {
|
||||
@@ -3964,7 +4058,7 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
|
||||
int32 t = unixtime();
|
||||
if (_peer->chat) {
|
||||
ChatData *chat = _peer->asChat();
|
||||
if (chat->forbidden) {
|
||||
if (chat->forbidden || chat->left) {
|
||||
text = lang(lng_chat_status_unaccessible);
|
||||
} else if (chat->participants.isEmpty()) {
|
||||
text = _titlePeerText.isEmpty() ? lng_chat_status_members(lt_count, chat->count < 0 ? 0 : chat->count) : _titlePeerText;
|
||||
@@ -4031,6 +4125,7 @@ void HistoryWidget::onFieldResize() {
|
||||
_attachDocument.move(0, height() - kbh - _attachDocument.height());
|
||||
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
|
||||
_botStart.setGeometry(0, _attachDocument.y(), width(), _botStart.height());
|
||||
_unblock.setGeometry(0, _attachDocument.y(), width(), _unblock.height());
|
||||
_send.move(width() - _send.width(), _attachDocument.y());
|
||||
_attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height());
|
||||
_kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height());
|
||||
@@ -4188,10 +4283,10 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||
connect(App::uploader(), SIGNAL(documentReady(MsgId, const MTPInputFile &)), this, SLOT(onDocumentUploaded(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(thumbDocumentReady(MsgId, const MTPInputFile &, const MTPInputFile &)), this, SLOT(onThumbDocumentUploaded(MsgId, const MTPInputFile &, const MTPInputFile &)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(audioReady(MsgId, const MTPInputFile &)), this, SLOT(onAudioUploaded(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
|
||||
// connect(App::uploader(), SIGNAL(photoProgress(MsgId)), this, SLOT(onPhotoProgress(MsgId)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(photoProgress(MsgId)), this, SLOT(onPhotoProgress(MsgId)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(documentProgress(MsgId)), this, SLOT(onDocumentProgress(MsgId)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(audioProgress(MsgId)), this, SLOT(onAudioProgress(MsgId)), Qt::UniqueConnection);
|
||||
// connect(App::uploader(), SIGNAL(photoFailed(MsgId)), this, SLOT(onPhotoFailed(MsgId)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(photoFailed(MsgId)), this, SLOT(onPhotoFailed(MsgId)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(documentFailed(MsgId)), this, SLOT(onDocumentFailed(MsgId)), Qt::UniqueConnection);
|
||||
connect(App::uploader(), SIGNAL(audioFailed(MsgId)), this, SLOT(onAudioFailed(MsgId)), Qt::UniqueConnection);
|
||||
|
||||
@@ -4204,11 +4299,11 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||
int32 flags = newMessageFlags(h->peer); // unread, out
|
||||
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
if (img.type == ToPreparePhoto) {
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup));
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup, MTPnullEntities));
|
||||
} else if (img.type == ToPrepareDocument) {
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup));
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup, MTPnullEntities));
|
||||
} else if (img.type == ToPrepareAudio) {
|
||||
h->addToBack(MTP_message(MTP_int(flags | MTPDmessage_flag_media_unread), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup));
|
||||
h->addToBack(MTP_message(MTP_int(flags | MTPDmessage_flag_media_unread), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities));
|
||||
}
|
||||
|
||||
if (_peer && img.peer == _peer->id) {
|
||||
@@ -4328,10 +4423,22 @@ void HistoryWidget::onAudioUploaded(MsgId newId, const MTPInputFile &file) {
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::onPhotoProgress(MsgId newId) {
|
||||
if (!MTP::authedId()) return;
|
||||
HistoryItem *item = App::histItemById(newId);
|
||||
if (item) {
|
||||
PhotoData *photo = (item->getMedia() && item->getMedia()->type() == MediaTypePhoto) ? static_cast<HistoryPhoto*>(item->getMedia())->photo() : 0;
|
||||
updateSendAction(item->history(), SendActionUploadPhoto, 0);
|
||||
// msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::onDocumentProgress(MsgId newId) {
|
||||
if (!MTP::authedId()) return;
|
||||
HistoryItem *item = App::histItemById(newId);
|
||||
if (item) {
|
||||
DocumentData *doc = (item->getMedia() && item->getMedia()->type() == MediaTypeDocument) ? static_cast<HistoryDocument*>(item->getMedia())->document() : 0;
|
||||
updateSendAction(item->history(), SendActionUploadFile, doc ? doc->uploadOffset : 0);
|
||||
msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
@@ -4340,14 +4447,26 @@ void HistoryWidget::onAudioProgress(MsgId newId) {
|
||||
if (!MTP::authedId()) return;
|
||||
HistoryItem *item = App::histItemById(newId);
|
||||
if (item) {
|
||||
AudioData *audio = (item->getMedia() && item->getMedia()->type() == MediaTypeAudio) ? static_cast<HistoryAudio*>(item->getMedia())->audio() : 0;
|
||||
updateSendAction(item->history(), SendActionUploadAudio, audio ? audio->uploadOffset : 0);
|
||||
msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::onPhotoFailed(MsgId newId) {
|
||||
if (!MTP::authedId()) return;
|
||||
HistoryItem *item = App::histItemById(newId);
|
||||
if (item) {
|
||||
updateSendAction(item->history(), SendActionUploadPhoto, -1);
|
||||
// msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::onDocumentFailed(MsgId newId) {
|
||||
if (!MTP::authedId()) return;
|
||||
HistoryItem *item = App::histItemById(newId);
|
||||
if (item) {
|
||||
updateSendAction(item->history(), SendActionUploadFile, -1);
|
||||
msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
@@ -4356,6 +4475,7 @@ void HistoryWidget::onAudioFailed(MsgId newId) {
|
||||
if (!MTP::authedId()) return;
|
||||
HistoryItem *item = App::histItemById(newId);
|
||||
if (item) {
|
||||
updateSendAction(item->history(), SendActionUploadAudio, -1);
|
||||
msgUpdated(item->history()->peer->id, item);
|
||||
}
|
||||
}
|
||||
@@ -4364,7 +4484,7 @@ void HistoryWidget::peerMessagesUpdated(PeerId peer) {
|
||||
if (_peer && _list && peer == _peer->id) {
|
||||
updateListSize();
|
||||
updateBotKeyboard();
|
||||
if (!_scroll.isHidden() && _botStart.isHidden() == isBotStart()) {
|
||||
if (!_scroll.isHidden() && !isBlocked() && _botStart.isHidden() == isBotStart()) {
|
||||
updateControlsVisibility();
|
||||
resizeEvent(0);
|
||||
}
|
||||
@@ -4405,6 +4525,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||
|
||||
_send.move(width() - _send.width(), _attachDocument.y());
|
||||
_botStart.setGeometry(0, _attachDocument.y(), width(), _botStart.height());
|
||||
_unblock.setGeometry(0, _attachDocument.y(), width(), _unblock.height());
|
||||
_attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height());
|
||||
_kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height());
|
||||
_kbHide.move(_attachEmoji.x(), _attachEmoji.y());
|
||||
@@ -4474,10 +4595,12 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
|
||||
}
|
||||
|
||||
int32 newScrollHeight = height();
|
||||
if (isBotStart()) {
|
||||
if (isBlocked()) {
|
||||
newScrollHeight -= _unblock.height();
|
||||
} else if (isBotStart()) {
|
||||
newScrollHeight -= _botStart.height();
|
||||
} else {
|
||||
if (!_peer->chat || !_peer->asChat()->forbidden) {
|
||||
if ((_peer->chat && !_peer->asChat()->forbidden && !_peer->asChat()->left) || (!_peer->chat && _peer->asUser()->access != UserNoAccess)) {
|
||||
newScrollHeight -= (_field.height() + 2 * st::sendPadding);
|
||||
}
|
||||
if (replyToId() || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0)) {
|
||||
@@ -4613,7 +4736,7 @@ void HistoryWidget::updateBotKeyboard() {
|
||||
bool hasMarkup = _keyboard.hasMarkup(), forceReply = _keyboard.forceReply() && !_replyTo;
|
||||
if (hasMarkup || forceReply) {
|
||||
if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == _history->lastKeyboardId && _history->lastKeyboardUsed) _kbWasHidden = true;
|
||||
if (!isBotStart() && (wasVisible || _replyTo || (_field.getLastText().isEmpty() && !_kbWasHidden))) {
|
||||
if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (_field.getLastText().isEmpty() && !_kbWasHidden))) {
|
||||
if (!_showAnim.animating()) {
|
||||
if (hasMarkup) {
|
||||
_kbScroll.show();
|
||||
@@ -4753,6 +4876,8 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) {
|
||||
App::main()->peerAfter(_peer, msgid, p, m);
|
||||
}
|
||||
if (p) App::main()->showPeerHistory(p->id, m);
|
||||
} else if (_history && (e->key() == Qt::Key_Search || e == QKeySequence::Find)) {
|
||||
App::main()->searchInPeer(_history->peer);
|
||||
} else {
|
||||
e->ignore();
|
||||
}
|
||||
@@ -5029,6 +5154,9 @@ void HistoryWidget::onFullPeerUpdated(PeerData *data) {
|
||||
updateControlsVisibility();
|
||||
resizeEvent(0);
|
||||
update();
|
||||
} else if (!_scroll.isHidden() && _unblock.isHidden() == isBlocked()) {
|
||||
updateControlsVisibility();
|
||||
resizeEvent(0);
|
||||
}
|
||||
if (newScrollTop != _scroll.scrollTop()) {
|
||||
if (_scroll.isVisible()) {
|
||||
@@ -5045,6 +5173,11 @@ void HistoryWidget::peerUpdated(PeerData *data) {
|
||||
if (!_showAnim.animating()) updateControlsVisibility();
|
||||
if (data->chat && data->asChat()->count > 0 && data->asChat()->participants.isEmpty()) {
|
||||
App::api()->requestFullPeer(data);
|
||||
} else if (!data->chat && data->asUser()->blocked == UserBlockUnknown) {
|
||||
App::api()->requestFullPeer(data);
|
||||
} else if (!_scroll.isHidden() && _unblock.isHidden() == isBlocked()) {
|
||||
updateControlsVisibility();
|
||||
resizeEvent(0);
|
||||
}
|
||||
App::main()->updateOnlineDisplay();
|
||||
}
|
||||
@@ -5160,7 +5293,7 @@ void HistoryWidget::updateTopBarSelection() {
|
||||
updateControlsVisibility();
|
||||
updateListSize();
|
||||
if (!App::wnd()->layerShown() && !App::passcoded()) {
|
||||
if (_selCount || (_list && _list->wasSelectedText()) || _recording || isBotStart()) {
|
||||
if (_selCount || (_list && _list->wasSelectedText()) || _recording || isBotStart() || isBlocked()) {
|
||||
_list->setFocus();
|
||||
} else {
|
||||
_field.setFocus();
|
||||
|
||||
@@ -386,10 +386,12 @@ public:
|
||||
|
||||
QRect historyRect() const;
|
||||
|
||||
void updateTyping(bool typing = true);
|
||||
void updateSendAction(History *history, SendActionType type, int32 progress = 0);
|
||||
void cancelSendAction(History *history, SendActionType type);
|
||||
|
||||
void updateRecentStickers();
|
||||
void stickersInstalled(uint64 setId);
|
||||
void typingDone(const MTPBool &result, mtpRequestId req);
|
||||
void sendActionDone(const MTPBool &result, mtpRequestId req);
|
||||
|
||||
void destroyData();
|
||||
void uploadImage(const QImage &img, bool withText = false, const QString &source = QString());
|
||||
@@ -489,6 +491,8 @@ public slots:
|
||||
void onReplyToMessage();
|
||||
void onReplyForwardPreviewCancel();
|
||||
|
||||
void onCancelSendAction();
|
||||
|
||||
void onStickerPackInfo();
|
||||
|
||||
void onPreviewParse();
|
||||
@@ -498,22 +502,23 @@ public slots:
|
||||
void peerUpdated(PeerData *data);
|
||||
void onFullPeerUpdated(PeerData *data);
|
||||
|
||||
void cancelTyping();
|
||||
|
||||
void onPhotoUploaded(MsgId msgId, const MTPInputFile &file);
|
||||
void onDocumentUploaded(MsgId msgId, const MTPInputFile &file);
|
||||
void onThumbDocumentUploaded(MsgId msgId, const MTPInputFile &file, const MTPInputFile &thumb);
|
||||
void onAudioUploaded(MsgId msgId, const MTPInputFile &file);
|
||||
|
||||
void onPhotoProgress(MsgId msgId);
|
||||
void onDocumentProgress(MsgId msgId);
|
||||
void onAudioProgress(MsgId msgId);
|
||||
|
||||
void onPhotoFailed(MsgId msgId);
|
||||
void onDocumentFailed(MsgId msgId);
|
||||
void onAudioFailed(MsgId msgId);
|
||||
|
||||
void onListScroll();
|
||||
void onHistoryToEnd();
|
||||
void onSend(bool ctrlShiftEnter = false, MsgId replyTo = -1);
|
||||
void onUnblock();
|
||||
void onBotStart();
|
||||
|
||||
void onPhotoSelect();
|
||||
@@ -600,6 +605,9 @@ private:
|
||||
void addMessagesToFront(const QVector<MTPMessage> &messages);
|
||||
void addMessagesToBack(const QVector<MTPMessage> &messages);
|
||||
|
||||
void unblockDone(PeerData *peer, const MTPBool &result);
|
||||
bool unblockFail(const RPCError &error);
|
||||
|
||||
void countHistoryShowFrom();
|
||||
|
||||
void updateToEndVisibility();
|
||||
@@ -636,9 +644,11 @@ private:
|
||||
MentionsDropdown _attachMention;
|
||||
|
||||
bool isBotStart() const;
|
||||
bool isBlocked() const;
|
||||
bool updateCmdStartShown();
|
||||
|
||||
FlatButton _send, _botStart;
|
||||
FlatButton _send, _unblock, _botStart;
|
||||
mtpRequestId _unblockRequest;
|
||||
IconedButton _attachDocument, _attachPhoto, _attachEmoji, _kbShow, _kbHide, _cmdStart;
|
||||
bool _cmdStartShown;
|
||||
MessageField _field;
|
||||
@@ -685,8 +695,8 @@ private:
|
||||
QTimer _animActiveTimer;
|
||||
float64 _animActiveStart;
|
||||
|
||||
mtpRequestId _typingRequest;
|
||||
QTimer _typingStopTimer;
|
||||
QMap<QPair<History*, SendActionType>, mtpRequestId> _sendActionRequests;
|
||||
QTimer _sendActionStopTimer;
|
||||
|
||||
uint64 _saveDraftStart;
|
||||
bool _saveDraftText;
|
||||
|
||||
@@ -28,7 +28,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_open_from_tray" = "Telegram öffnen";
|
||||
"lng_minimize_to_tray" = "Minimieren";
|
||||
"lng_quit_from_tray" = "Telegram beenden";
|
||||
"lng_tray_icon_text" = "Telegram ist noch aktiv,\ndu kannst das in den Einstellungen anpassen.\n\nWenn dieses Symbol aus der Taskleiste verschwindet,\nkannst du es wieder hierher ziehen.";
|
||||
"lng_tray_icon_text" = "Telegram ist minimiert und läuft im Hintergrund,\ndu kannst das in den Einstellungen ändern.\nUm Telegram wieder anzuzeigen, klicke auf \ndas Symbol im Benachrichtigungsfeld.";
|
||||
|
||||
"lng_month1" = "Januar";
|
||||
"lng_month2" = "Februar";
|
||||
@@ -69,6 +69,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "Jetzt versuchen";
|
||||
|
||||
"lng_status_service_notifications" = "Servicemeldungen";
|
||||
"lng_status_support" = "Support";
|
||||
"lng_status_bot" = "Bot";
|
||||
"lng_status_bot_reads_all" = "hat Zugriff auf Nachrichten";
|
||||
"lng_status_bot_not_reads_all" = "hat keinen Zugriff auf Nachrichten";
|
||||
@@ -156,8 +157,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_dlg_new_group_name" = "Name der Gruppe";
|
||||
"lng_dlg_create_group" = "Erstellen";
|
||||
"lng_no_contacts" = "Du hast keine Kontakte";
|
||||
"lng_no_chats" = "Noch keine Chats";
|
||||
"lng_contacts_loading" = "Lade..";
|
||||
"lng_contacts_not_found" = "Keine Kontakte gefunden";
|
||||
"lng_dlg_search_chat" = "In diesem Chat suchen";
|
||||
"lng_dlg_search_for_messages" = "Nach Nachrichten suchen";
|
||||
|
||||
"lng_settings_save" = "Speichern";
|
||||
"lng_settings_upload" = "Profilbild festlegen";
|
||||
@@ -180,8 +184,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_settings_section_notify" = "Benachrichtigungen";
|
||||
"lng_settings_desktop_notify" = "Desktopbenachrichtigungen";
|
||||
"lng_settings_show_name" = "Sendername anzeigen";
|
||||
"lng_settings_show_name" = "Absendername anzeigen";
|
||||
"lng_settings_show_preview" = "Nachrichtenvorschau anzeigen";
|
||||
"lng_settings_use_windows" = "Windows Benachrichtigungen";
|
||||
"lng_settings_sound_notify" = "Ton abspielen";
|
||||
|
||||
"lng_notification_preview" = "Du hast eine neue Nachricht";
|
||||
@@ -289,7 +294,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_bad" = "Kennwort und Hinweis müssen sich unterscheiden.";
|
||||
"lng_cloud_password_email" = "E-Mail für die Wiederherstellung";
|
||||
"lng_cloud_password_bad_email" = "Ungültige E-Mai, bitte erneut versuchen.";
|
||||
"lng_cloud_password_about" = "Du kannst ein eigenes Kennwort festlegen, um dich an einem neuen Gerät anzumelden, zusätzlich zum SMS-Code.";
|
||||
"lng_cloud_password_about" = "Dieses Kennwort brauchst du, wenn du dich mit einem neuen Gerät anmeldest.";
|
||||
"lng_cloud_password_about_recover" = "Hinweis! Möchtest du wirklich keine E-Mail\nAdresse hinterlegen? \n\nWenn dir dein Kennwort nicht mehr einfällt, \nverlierst du Zugriff auf dein Telegram Konto.";
|
||||
"lng_cloud_password_almost" = "Ein Bestätigungslink wurde an\ndeine E-Mail Adresse gesendet.\n\nZweistufige Bestätigung wird aktiviert,\nsobald du den Link öffnest.";
|
||||
"lng_cloud_password_was_set" = "Zweistufige Bestätigung aktiviert.";
|
||||
@@ -320,6 +325,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_reset_one_sure" = "Dieses Gerät wirklich abmelden?";
|
||||
"lng_settings_reset_button" = "Beenden";
|
||||
"lng_settings_reset_done" = "Alle anderen Sitzungen wurden erfolgreich beendet.";
|
||||
"lng_settings_ask_question" = "Eine Frage stellen";
|
||||
"lng_settings_ask_sure" = "Bedenke bitte, dass der Telegram Support von ehrenamtlichen Helfern betreut wird.\n\nKennst du schon die Telegram FAQ? Dort findest du Antworten auf die am häufigsten gestellten Fragen.";
|
||||
"lng_settings_faq_button" = "FAQ öffnen";
|
||||
"lng_settings_ask_ok" = "Frage stellen";
|
||||
"lng_settings_faq" = "Telegram FAQ";
|
||||
"lng_settings_logout" = "Abmelden";
|
||||
"lng_sure_logout" = "Du kannst Telegram von all deinen Geräten gleichzeitig nutzen. Wirklich abmelden?";
|
||||
|
||||
@@ -339,6 +349,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_topbar_info" = "Info";
|
||||
"lng_profile_about_section" = "Info";
|
||||
"lng_profile_settings_section" = "Einstellungen";
|
||||
"lng_profile_actions_section" = "Aktionen";
|
||||
"lng_profile_bot_settings" = "Einstellungen";
|
||||
"lng_profile_bot_help" = "Hilfe";
|
||||
"lng_profile_participants_section" = "Teilnehmer";
|
||||
@@ -348,6 +359,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_edit_contact" = "Bearbeiten";
|
||||
"lng_profile_enable_notifications" = "Benachrichtigungen";
|
||||
"lng_profile_clear_history" = "Chatverlauf löschen";
|
||||
"lng_profile_delete_conversation" = "Chat entfernen";
|
||||
"lng_profile_clear_and_exit" = "Löschen und verlassen";
|
||||
"lng_profile_search_messages" = "In diesem Chat suchen";
|
||||
"lng_profile_block_user" = "Blockieren";
|
||||
"lng_profile_unblock_user" = "Freigeben";
|
||||
"lng_profile_block_bot" = "Bot anhalten und blockieren";
|
||||
"lng_profile_unblock_bot" = "Bot freigeben";
|
||||
"lng_profile_send_message" = "Nachricht senden";
|
||||
"lng_profile_share_contact" = "Kontakt teilen";
|
||||
"lng_profile_invite_to_group" = "In eine Gruppe einladen";
|
||||
@@ -379,13 +397,16 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "Neue Gruppe erstellen";
|
||||
|
||||
"lng_failed_add_participant" = "Kann Teilnehmer nicht hinzufügen. Später erneut versuchen.";
|
||||
"lng_failed_add_not_mutual" = "Wenn man eine Gruppe verlässt, kann nur \nein gemeinsamer Kontakt die Person erneut \neinladen (beide Seiten müssen die Nummer\n des anderen gespeichert haben).";
|
||||
|
||||
"lng_sure_delete_contact" = "Bist du sicher, dass du {contact} von deinen Kontakten löschen willst?";
|
||||
"lng_sure_delete_history" = "Sicher, dass du den kompletten Verlauf mit {contact} löschen willst?\n\nDas kann man nicht rückgängig machen.";
|
||||
"lng_sure_delete_group_history" = "Möchtest du wirklich deinen Verlauf von «{group}» löschen?\n\nDas kann man nicht rückgängig machen.";
|
||||
|
||||
"lng_sure_delete_and_exit" = "Deinen Verlauf von «{group}» löschen und die Gruppe verlassen?\n\nDas kann man nicht rückgängig machen.";
|
||||
|
||||
"lng_message_empty" = "(empty)";
|
||||
"lng_message_empty" = "Leere Nachricht";
|
||||
"lng_media_unsupported" = "Format Nicht Unterstützt";
|
||||
|
||||
"lng_action_add_user" = "{from} hat {user} hinzugefügt";
|
||||
"lng_action_kick_user" = "{from} hat {user} entfernt";
|
||||
@@ -461,10 +482,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_message_ph" = "Schreibe deine Nachricht..";
|
||||
"lng_record_cancel" = "Zum Abbrechen rausbewegen";
|
||||
"lng_empty_history" = "";
|
||||
"lng_willbe_history" = "Wähle einen Chat aus, um zu schreiben";
|
||||
"lng_willbe_history" = "Chat auswählen um zu schreiben";
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "Ich";
|
||||
"lng_bot_description" = "Was kann dieser Bot?";
|
||||
"lng_unblock_button" = "Freigeben";
|
||||
|
||||
"lng_bot_start" = "Starten";
|
||||
"lng_bot_choose_group" = "Gruppe auswählen";
|
||||
@@ -477,6 +499,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_user_typing" = "{user} tippt";
|
||||
"lng_users_typing" = "{user} und {second_user} tippen";
|
||||
"lng_many_typing" = "{count:_not_used_|# tippt|# tippen}";
|
||||
"lng_send_action_record_video" = "schickt Video";
|
||||
"lng_user_action_record_video" = "{user} sendet Video";
|
||||
"lng_send_action_upload_video" = "schickt Video";
|
||||
"lng_user_action_upload_video" = "{user} sendet Video";
|
||||
"lng_send_action_record_audio" = "nimmt Audio auf";
|
||||
"lng_user_action_record_audio" = "{user} nimmt Audio auf";
|
||||
"lng_send_action_upload_audio" = "nimmt Audio auf";
|
||||
"lng_user_action_upload_audio" = "{user} sendet Audio";
|
||||
"lng_send_action_upload_photo" = "sendet Bild";
|
||||
"lng_user_action_upload_photo" = "{user} sendet Bild";
|
||||
"lng_send_action_upload_file" = "sendet Datei";
|
||||
"lng_user_action_upload_file" = "{user} sendet Datei";
|
||||
"lng_send_action_geo_location" = "wählt Standort aus";
|
||||
"lng_user_action_geo_location" = "{user} wählt Standort aus";
|
||||
"lng_send_action_choose_contact" = "wählt Kontakt aus";
|
||||
"lng_user_action_choose_contact" = "{user} wählt Kontakt aus";
|
||||
"lng_unread_bar" = "{count:_not_used_|# Ungelesene Nachricht|# Ungelesene Nachrichten}";
|
||||
|
||||
"lng_maps_point" = "Standort";
|
||||
@@ -603,7 +641,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
|
||||
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
||||
"lng_new_version_text" = "— In-App Medienwiedergabe optimiert\n— Fehlerbehebungen und kleinere Verbesserungen";
|
||||
"lng_new_version_text" = "— Direkte Suche in Chats (Chat auswählen und STRG+F drücken)\n— Verlauf in Gruppen löschen (in der Gruppe auf den Gruppennamen tippen)\n— Kontakte, mit denen du nicht chattest, werden nicht mehr in der Übersicht gezeigt";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_open_from_tray" = "Abrir Telegram";
|
||||
"lng_minimize_to_tray" = "Minimizar al icono";
|
||||
"lng_quit_from_tray" = "Salir de Telegram";
|
||||
"lng_tray_icon_text" = "Telegram sigue funcionando aquí, \npuedes cambiar esto desde los ajustes.\n\nSi este ícono desaparece desde el menú,\npuedes arrastrarlo de regreso desde los iconos ocultos.";
|
||||
"lng_tray_icon_text" = "Telegram aún está funcionando,\npuedes cambiar esto en los ajustes. \nSi este icono desaparece del menú, \npuedes arrastrarlo aquí desde los iconos ocultos.";
|
||||
|
||||
"lng_month1" = "enero";
|
||||
"lng_month2" = "febrero";
|
||||
@@ -69,6 +69,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "Intentar ahora";
|
||||
|
||||
"lng_status_service_notifications" = "servicio de notificaciones";
|
||||
"lng_status_support" = "soporte";
|
||||
"lng_status_bot" = "bot";
|
||||
"lng_status_bot_reads_all" = "tiene acceso a los mensajes";
|
||||
"lng_status_bot_not_reads_all" = "no tiene acceso a los mensajes";
|
||||
@@ -156,8 +157,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_dlg_new_group_name" = "Nombre del grupo";
|
||||
"lng_dlg_create_group" = "Crear";
|
||||
"lng_no_contacts" = "No tienes contactos";
|
||||
"lng_no_chats" = "Tus chats estarán aquí";
|
||||
"lng_contacts_loading" = "Cargando...";
|
||||
"lng_contacts_not_found" = "No se encontraron contactos";
|
||||
"lng_dlg_search_chat" = "Buscar en este chat";
|
||||
"lng_dlg_search_for_messages" = "Buscar mensajes";
|
||||
|
||||
"lng_settings_save" = "Guardar";
|
||||
"lng_settings_upload" = "Poner foto de perfil";
|
||||
@@ -182,6 +186,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_desktop_notify" = "Notificaciones de escritorio";
|
||||
"lng_settings_show_name" = "Mostrar el nombre del remitente";
|
||||
"lng_settings_show_preview" = "Mostrar la vista previa del mensaje";
|
||||
"lng_settings_use_windows" = "Usar notificaciones de Windows";
|
||||
"lng_settings_sound_notify" = "Reproducir sonido";
|
||||
|
||||
"lng_notification_preview" = "Tienes un nuevo mensaje";
|
||||
@@ -289,7 +294,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_bad" = "La contraseña y la pista no pueden ser iguales.";
|
||||
"lng_cloud_password_email" = "Pon un e-mail de recuperación";
|
||||
"lng_cloud_password_bad_email" = "E-mail incorrecto. Por favor, prueba otro.";
|
||||
"lng_cloud_password_about" = "Esta contraseña será requerida cuando inicies sesión en un nuevo dispositivo, además del código de activación.";
|
||||
"lng_cloud_password_about" = "Necesitarás la contraseña al iniciar sesión en un nuevo dispositivo, además del código de activación.";
|
||||
"lng_cloud_password_about_recover" = "¡Advertencia! ¿No quieres añadir un e-mail \nde recuperación para la contraseña?\n\nSi olvidas tu contraseña, perderás\nel acceso a tu cuenta de Telegram.";
|
||||
"lng_cloud_password_almost" = "Un enlace de confirmación fue enviado\nal e-mail que estableciste.\n\nLa verificación en dos pasos se activará\nen cuanto sigas ese enlace.";
|
||||
"lng_cloud_password_was_set" = "Verificación en dos pasos activada.";
|
||||
@@ -320,6 +325,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_reset_one_sure" = "¿Quieres cerrar esta sesión?";
|
||||
"lng_settings_reset_button" = "Cerrar";
|
||||
"lng_settings_reset_done" = "Se cerraron las otras sesiones";
|
||||
"lng_settings_ask_question" = "Hacer una pregunta";
|
||||
"lng_settings_ask_sure" = "Por favor, considera que el soporte de Telegram está hecho por voluntarios. Respondemos lo antes posible, pero puede tomar tiempo.\n\nSi quieres, mira las preguntas frecuentes de Telegram: tienen soluciones a problemas y respuestas para la mayoría de las preguntas.";
|
||||
"lng_settings_faq_button" = "Preguntas frecuentes";
|
||||
"lng_settings_ask_ok" = "Preguntar";
|
||||
"lng_settings_faq" = "Preguntas frecuentes";
|
||||
"lng_settings_logout" = "Cerrar sesión";
|
||||
"lng_sure_logout" = "¿Quieres cerrar sesión?";
|
||||
|
||||
@@ -339,6 +349,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_topbar_info" = "Información";
|
||||
"lng_profile_about_section" = "Acerca de";
|
||||
"lng_profile_settings_section" = "Ajustes";
|
||||
"lng_profile_actions_section" = "Acciones";
|
||||
"lng_profile_bot_settings" = "Ajustes";
|
||||
"lng_profile_bot_help" = "Ayuda";
|
||||
"lng_profile_participants_section" = "Miembros";
|
||||
@@ -348,6 +359,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_edit_contact" = "Editar";
|
||||
"lng_profile_enable_notifications" = "Notificaciones";
|
||||
"lng_profile_clear_history" = "Borrar historial";
|
||||
"lng_profile_delete_conversation" = "Eliminar chat";
|
||||
"lng_profile_clear_and_exit" = "Eliminar y salir";
|
||||
"lng_profile_search_messages" = "Buscar mensajes";
|
||||
"lng_profile_block_user" = "Bloquear";
|
||||
"lng_profile_unblock_user" = "Desbloquear";
|
||||
"lng_profile_block_bot" = "Detener y bloquear el bot";
|
||||
"lng_profile_unblock_bot" = "Desbloquear el bot";
|
||||
"lng_profile_send_message" = "Enviar mensaje";
|
||||
"lng_profile_share_contact" = "Compartir contacto";
|
||||
"lng_profile_invite_to_group" = "Añadir al grupo";
|
||||
@@ -359,7 +377,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_sure_kick" = "¿Quieres expulsar a {user} del grupo?";
|
||||
"lng_profile_loading" = "Cargando...";
|
||||
"lng_profile_shared_media" = "Todos los archivos";
|
||||
"lng_profile_no_media" = "No hay multimedia en esta conversación.";
|
||||
"lng_profile_no_media" = "No hay multimedia en este chat.";
|
||||
"lng_profile_photos" = "{count:_not_used_|# foto|# fotos} »";
|
||||
"lng_profile_photos_header" = "Todas las fotos";
|
||||
"lng_profile_videos" = "{count:_not_used_|# vídeo|# vídeos} »";
|
||||
@@ -379,13 +397,16 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "Nuevo grupo";
|
||||
|
||||
"lng_failed_add_participant" = "No se pudo añadir el usuario. Por favor, inténtalo más tarde.";
|
||||
"lng_failed_add_not_mutual" = "Si una persona dejó el grupo, sólo\nun contacto mutuo puede volver \na invitarlo (necesitan tener tu \nnúmero y tú el de ellos).";
|
||||
|
||||
"lng_sure_delete_contact" = "¿Quieres eliminar a {contact} de tu lista de contactos?";
|
||||
"lng_sure_delete_history" = "¿Quieres eliminar todo el historial de mensajes con {contact}?\n\nEsta acción no se puede deshacer.";
|
||||
"lng_sure_delete_group_history" = "¿Quieres borrar todo el historial en «{group}»?\n\nEsta acción no se puede deshacer.";
|
||||
|
||||
"lng_sure_delete_and_exit" = "¿Quieres eliminar todo el historial de mensajes y dejar el grupo «{group}»?\n\nEsta acción no se puede deshacer.";
|
||||
|
||||
"lng_message_empty" = "(vacío)";
|
||||
"lng_message_empty" = "Mensaje vacío";
|
||||
"lng_media_unsupported" = "Multimedia no soportada";
|
||||
|
||||
"lng_action_add_user" = "{from} añadió a {user}";
|
||||
"lng_action_kick_user" = "{from} expulsó a {user}";
|
||||
@@ -461,10 +482,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_message_ph" = "Escribir un mensaje...";
|
||||
"lng_record_cancel" = "Suelta fuera de aquí para cancelar";
|
||||
"lng_empty_history" = "";
|
||||
"lng_willbe_history" = "Por favor, elige un chat para comenzar a conversar";
|
||||
"lng_willbe_history" = "Por favor, elige un chat para comenzar";
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "Tú";
|
||||
"lng_bot_description" = "¿Qué puede hacer este bot?";
|
||||
"lng_unblock_button" = "Desbloquear";
|
||||
|
||||
"lng_bot_start" = "Iniciar";
|
||||
"lng_bot_choose_group" = "Elegir grupo";
|
||||
@@ -477,6 +499,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_user_typing" = "{user} está escribiendo";
|
||||
"lng_users_typing" = "{user} y {second_user} están escribiendo";
|
||||
"lng_many_typing" = "{count:_not_used_|# está|# están} escribiendo";
|
||||
"lng_send_action_record_video" = "grabando vídeo";
|
||||
"lng_user_action_record_video" = "{user} está grabando un vídeo";
|
||||
"lng_send_action_upload_video" = "enviando vídeo";
|
||||
"lng_user_action_upload_video" = "{user} está enviando un vídeo";
|
||||
"lng_send_action_record_audio" = "grabando audio";
|
||||
"lng_user_action_record_audio" = "{user} está grabando un audio";
|
||||
"lng_send_action_upload_audio" = "enviando audio";
|
||||
"lng_user_action_upload_audio" = "{user} está enviando un audio";
|
||||
"lng_send_action_upload_photo" = "enviando foto";
|
||||
"lng_user_action_upload_photo" = "{user} está enviando una foto";
|
||||
"lng_send_action_upload_file" = "enviando archivo";
|
||||
"lng_user_action_upload_file" = "{user} está enviando un archivo";
|
||||
"lng_send_action_geo_location" = "obteniendo ubicación";
|
||||
"lng_user_action_geo_location" = "{user} está obteniendo una ubicación";
|
||||
"lng_send_action_choose_contact" = "eligiendo contacto";
|
||||
"lng_user_action_choose_contact" = "{user} está eligiendo un contacto";
|
||||
"lng_unread_bar" = "{count:_not_used_|# mensaje sin leer|# mensajes sin leer}";
|
||||
|
||||
"lng_maps_point" = "Ubicación";
|
||||
@@ -603,7 +641,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop fue actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
|
||||
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
|
||||
"lng_new_version_text" = "— Reproducción de la multimedia dentro de la aplicación mejorada\n— Corrección de errores y otras mejoras menores";
|
||||
"lng_new_version_text" = "— Busca mensajes en un chat\n— Borra el historial de mensajes en grupos\n— Los contactos sin mensajes se ocultarán de la lista de chats";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_menu_back" = "Indietro";
|
||||
|
||||
"lng_open_from_tray" = "Apri Telegram";
|
||||
"lng_minimize_to_tray" = "Minimizza";
|
||||
"lng_minimize_to_tray" = "Riduci a icona";
|
||||
"lng_quit_from_tray" = "Chiudi Telegram";
|
||||
"lng_tray_icon_text" = "Telegram è ancora aperto qui,\npuoi cambiare questo nelle impostazioni.\n\nSe l'icona scompare dall'area di notifica,\npuoi riportarla indietro dalle icone nascoste.";
|
||||
"lng_tray_icon_text" = "Telegram è ancora attivo qui,\npuoi modificarlo nelle impostazioni.\nSe l'icona scompare dall'area di notifica,\npuoi ripristinarla dalle icone nascoste.";
|
||||
|
||||
"lng_month1" = "Gennaio";
|
||||
"lng_month2" = "Febbraio";
|
||||
@@ -69,6 +69,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "Prova ora";
|
||||
|
||||
"lng_status_service_notifications" = "notifiche di servizio";
|
||||
"lng_status_support" = "supporto";
|
||||
"lng_status_bot" = "bot";
|
||||
"lng_status_bot_reads_all" = "ha accesso ai messaggi";
|
||||
"lng_status_bot_not_reads_all" = "non ha accesso ai messaggi";
|
||||
@@ -156,8 +157,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_dlg_new_group_name" = "Nome gruppo";
|
||||
"lng_dlg_create_group" = "Crea";
|
||||
"lng_no_contacts" = "Non hai contatti";
|
||||
"lng_no_chats" = "Le tua chat saranno qui";
|
||||
"lng_contacts_loading" = "Caricamento..";
|
||||
"lng_contacts_not_found" = "Nessun contatto trovato";
|
||||
"lng_dlg_search_chat" = "Cerca in questa chat";
|
||||
"lng_dlg_search_for_messages" = "Cerca messaggi";
|
||||
|
||||
"lng_settings_save" = "Salva";
|
||||
"lng_settings_upload" = "Imposta foto profilo";
|
||||
@@ -182,6 +186,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_desktop_notify" = "Notifiche desktop";
|
||||
"lng_settings_show_name" = "Mostra nome del mittente";
|
||||
"lng_settings_show_preview" = "Mostra anteprima messaggio";
|
||||
"lng_settings_use_windows" = "Usa le notifiche di Windows";
|
||||
"lng_settings_sound_notify" = "Riproduci suono";
|
||||
|
||||
"lng_notification_preview" = "Hai un nuovo messaggio";
|
||||
@@ -267,7 +272,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_passcode_enter_first" = "Inserisci un codice";
|
||||
"lng_passcode_enter_new" = "Inserisci il nuovo codice";
|
||||
"lng_passcode_confirm_new" = "Reinserisci il nuovo codice";
|
||||
"lng_passcode_about" = "Quando imposti un codice, un'icona col lucchetto apparirà nel menu in alto. Premi su di essa per bloccare l'app. \n\nNota: se ti dimentichi il codice, dovrai rifare il login su Telegram Desktop.";
|
||||
"lng_passcode_about" = "Quando imposti un codice, un'icona col lucchetto apparirà nel menu in alto. Premi su di essa per bloccare l'app. \n\nNota: se dimentichi il codice, dovrai rifare l'accesso su Telegram Desktop.";
|
||||
"lng_passcode_differ" = "I codici sono diversi";
|
||||
"lng_passcode_wrong" = "Codice errato";
|
||||
"lng_passcode_is_same" = "Il codice non è stato cambiato";
|
||||
@@ -320,6 +325,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_reset_one_sure" = "Vuoi terminare questa sessione?";
|
||||
"lng_settings_reset_button" = "Chiudi";
|
||||
"lng_settings_reset_done" = "Altre sessioni terminate";
|
||||
"lng_settings_ask_question" = "Fai una domanda";
|
||||
"lng_settings_ask_sure" = "Per favore, considera che il supporto su Telegram è offerto da volontari. Proveremo a risponderti il più velocemente possibile, ma potrebbe volerci un po' di tempo.\n\nDai un'occhiata alle FAQ di Telegram: potrai trovare importanti suggerimenti riguardo alcune problematiche e risposte alla maggior parte delle domande.";
|
||||
"lng_settings_faq_button" = "Vai alle FAQ";
|
||||
"lng_settings_ask_ok" = "Chiedi";
|
||||
"lng_settings_faq" = "FAQ di Telegram";
|
||||
"lng_settings_logout" = "Disconnetti";
|
||||
"lng_sure_logout" = "Sicuro di volerti disconnettere?";
|
||||
|
||||
@@ -339,6 +349,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_topbar_info" = "Info";
|
||||
"lng_profile_about_section" = "Info";
|
||||
"lng_profile_settings_section" = "Impostazioni";
|
||||
"lng_profile_actions_section" = "Azioni";
|
||||
"lng_profile_bot_settings" = "Impostazioni";
|
||||
"lng_profile_bot_help" = "Aiuto";
|
||||
"lng_profile_participants_section" = "Membri";
|
||||
@@ -348,6 +359,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_edit_contact" = "Modifica";
|
||||
"lng_profile_enable_notifications" = "Notifiche";
|
||||
"lng_profile_clear_history" = "Cancella la cronologia";
|
||||
"lng_profile_delete_conversation" = "Elimina chat";
|
||||
"lng_profile_clear_and_exit" = "Elimina ed esci";
|
||||
"lng_profile_search_messages" = "Cerca messaggi";
|
||||
"lng_profile_block_user" = "Blocca utente";
|
||||
"lng_profile_unblock_user" = "Sblocca utente";
|
||||
"lng_profile_block_bot" = "Arresta e blocca bot";
|
||||
"lng_profile_unblock_bot" = "Sblocca bot";
|
||||
"lng_profile_send_message" = "Invia messaggio";
|
||||
"lng_profile_share_contact" = "Condividi contatto";
|
||||
"lng_profile_invite_to_group" = "Aggiungi a un gruppo";
|
||||
@@ -379,13 +397,16 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "Nuovo gruppo";
|
||||
|
||||
"lng_failed_add_participant" = "Impossibile aggiungere l'utente. Riprova più tardi.";
|
||||
"lng_failed_add_not_mutual" = "Se una persona lascia un gruppo,\nsolo un contatto in comune può reinvitarlo\n(devono avere il tuo numero\ndi telefono, e tu il loro).";
|
||||
|
||||
"lng_sure_delete_contact" = "Sicuro di volere eliminare {contact} dalla tua lista dei contatti?";
|
||||
"lng_sure_delete_history" = "Sicuro di voler eliminare tutta la cronologia dei messaggi con {contact}?\n\nQuesta azione non può essere annullata.";
|
||||
"lng_sure_delete_group_history" = "Sicuro di voler eliminare tutta la cronologia dei messaggi in «{group}»?\n\nQuesta azione non può essere annullata.";
|
||||
|
||||
"lng_sure_delete_and_exit" = "Sicuro di voler eliminare tutta la cronologia dei messaggi e abbandonare «{group}»?\n\nQuesta azione non può essere annullata.";
|
||||
|
||||
"lng_message_empty" = "(vuoto)";
|
||||
"lng_message_empty" = "Messaggio vuoto";
|
||||
"lng_media_unsupported" = "Media non supportato";
|
||||
|
||||
"lng_action_add_user" = "{from} ha aggiunto {user}";
|
||||
"lng_action_kick_user" = "{from} ha rimosso {user}";
|
||||
@@ -465,6 +486,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "Tu";
|
||||
"lng_bot_description" = "Cosa può fare questo bot?";
|
||||
"lng_unblock_button" = "Sblocca";
|
||||
|
||||
"lng_bot_start" = "Avvia";
|
||||
"lng_bot_choose_group" = "Scegli gruppo";
|
||||
@@ -477,6 +499,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_user_typing" = "{user} sta scrivendo";
|
||||
"lng_users_typing" = "{user} e {second_user} stanno scrivendo";
|
||||
"lng_many_typing" = "{count:_not_used_|# sta|# stanno} scrivendo";
|
||||
"lng_send_action_record_video" = "registrando un video";
|
||||
"lng_user_action_record_video" = "{user} sta registrando un video";
|
||||
"lng_send_action_upload_video" = "inviando un video";
|
||||
"lng_user_action_upload_video" = "{user} sta inviando un video";
|
||||
"lng_send_action_record_audio" = "registrando un audio";
|
||||
"lng_user_action_record_audio" = "{user} sta registrando un audio";
|
||||
"lng_send_action_upload_audio" = "inviando un audio";
|
||||
"lng_user_action_upload_audio" = "{user} sta inviando un audio";
|
||||
"lng_send_action_upload_photo" = "inviando una foto";
|
||||
"lng_user_action_upload_photo" = "{user} sta inviando una foto";
|
||||
"lng_send_action_upload_file" = "inviando un file";
|
||||
"lng_user_action_upload_file" = "{user} sta inviando un file";
|
||||
"lng_send_action_geo_location" = "selezionando una posizione";
|
||||
"lng_user_action_geo_location" = "{user} sta selezionando una posizione";
|
||||
"lng_send_action_choose_contact" = "selezionando un contatto";
|
||||
"lng_user_action_choose_contact" = "{user} sta selezionando un contatto";
|
||||
"lng_unread_bar" = "{count:_not_used_|# messaggio non letto|# messaggi non letti}";
|
||||
|
||||
"lng_maps_point" = "Posizione";
|
||||
@@ -603,7 +641,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli update è disponibile qui:\n{link}";
|
||||
"lng_new_version_minor" = "— Bug fix e altri miglioramenti minori";
|
||||
"lng_new_version_text" = "— Riproduzione dei media migliorata\n— Risoluzione di bug e miglioramenti minori";
|
||||
"lng_new_version_text" = "— Cerca messaggi in una chat\n— Pulisci la cronologia dei messaggi nei gruppi\n— I contatti senza messaggi sono nascosti dalla lista delle chat";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_open_from_tray" = "텔레그램 실행";
|
||||
"lng_minimize_to_tray" = "창을 최소화";
|
||||
"lng_quit_from_tray" = "텔레그램 종료";
|
||||
"lng_tray_icon_text" = "텔레그램은 아직 실행중입니다.\n설정 화면에서 실행설정을 변경하실 수 있습니다.\n\n트레이메뉴에서 이 아이콘이 사라질 경우.\n숨겨진 아이콘 목록에서 다시 복원할 수 있습니다.";
|
||||
"lng_tray_icon_text" = "텔레그램은 아직 실행중입니다. \n설정 화면에서 실행설정을 변경하실 수 있습니다. \n트레이메뉴에서 이 아이콘이 사라질 경우. \n숨겨진 아이콘 목록에서 다시 복원할 수 있습니다.";
|
||||
|
||||
"lng_month1" = "1월";
|
||||
"lng_month2" = "2월";
|
||||
@@ -69,6 +69,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "다시 시도";
|
||||
|
||||
"lng_status_service_notifications" = "서비스 알림";
|
||||
"lng_status_support" = "support";
|
||||
"lng_status_bot" = "bot";
|
||||
"lng_status_bot_reads_all" = "메시지 접근 권한이 있습니다.";
|
||||
"lng_status_bot_not_reads_all" = "메시지 접근 권한이 없습니다.";
|
||||
@@ -156,8 +157,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_dlg_new_group_name" = "그룹이름";
|
||||
"lng_dlg_create_group" = "만들기";
|
||||
"lng_no_contacts" = "연락처가 없습니다.";
|
||||
"lng_no_chats" = "대화시 대화방이 존재 할 곳입니다.";
|
||||
"lng_contacts_loading" = "로드중..";
|
||||
"lng_contacts_not_found" = "연락처를 찾을 수 없음";
|
||||
"lng_dlg_search_chat" = "이 채팅에서 검색";
|
||||
"lng_dlg_search_for_messages" = "메시지 검색";
|
||||
|
||||
"lng_settings_save" = "저장";
|
||||
"lng_settings_upload" = "프로필 이미지 선택";
|
||||
@@ -182,6 +186,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_desktop_notify" = "데스크탑 알림";
|
||||
"lng_settings_show_name" = "발신인 표시";
|
||||
"lng_settings_show_preview" = "메시지 미리보기";
|
||||
"lng_settings_use_windows" = "Use Windows notifications";
|
||||
"lng_settings_sound_notify" = "소리 재생";
|
||||
|
||||
"lng_notification_preview" = "새로운 메시지가 있습니다.";
|
||||
@@ -320,6 +325,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_reset_one_sure" = "해당 세션을 강제 종료 하시겠습니까?";
|
||||
"lng_settings_reset_button" = "종료";
|
||||
"lng_settings_reset_done" = "다른 모든 세션이 강제 종료 되었습니다.";
|
||||
"lng_settings_ask_question" = "Ask a Question";
|
||||
"lng_settings_ask_sure" = "Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.\n\nPlease take a look at the Telegram FAQ: it has important troubleshooting tips and answers to most questions.";
|
||||
"lng_settings_faq_button" = "Go to FAQ";
|
||||
"lng_settings_ask_ok" = "Ask";
|
||||
"lng_settings_faq" = "Telegram FAQ";
|
||||
"lng_settings_logout" = "로그아웃";
|
||||
"lng_sure_logout" = "로그아웃을 하시겠습니까?";
|
||||
|
||||
@@ -339,6 +349,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_topbar_info" = "정보";
|
||||
"lng_profile_about_section" = "취소";
|
||||
"lng_profile_settings_section" = "환경설정";
|
||||
"lng_profile_actions_section" = "동작";
|
||||
"lng_profile_bot_settings" = "환경설정";
|
||||
"lng_profile_bot_help" = "도움말";
|
||||
"lng_profile_participants_section" = "사용자";
|
||||
@@ -348,6 +359,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_edit_contact" = "수정";
|
||||
"lng_profile_enable_notifications" = "알림";
|
||||
"lng_profile_clear_history" = "히스토리 초기화";
|
||||
"lng_profile_delete_conversation" = "대화 지우기";
|
||||
"lng_profile_clear_and_exit" = "삭제 후 종료";
|
||||
"lng_profile_search_messages" = "메시지 검색";
|
||||
"lng_profile_block_user" = "Block user";
|
||||
"lng_profile_unblock_user" = "Unblock user";
|
||||
"lng_profile_block_bot" = "Stop and block bot";
|
||||
"lng_profile_unblock_bot" = "Unblock bot";
|
||||
"lng_profile_send_message" = "메세지 전송";
|
||||
"lng_profile_share_contact" = "연락처 공유";
|
||||
"lng_profile_invite_to_group" = "그룹에 추가";
|
||||
@@ -379,13 +397,16 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "새로운 그룹";
|
||||
|
||||
"lng_failed_add_participant" = "사용자를 초대할 수 없습니다. 나중에 다시 시도해주세요.";
|
||||
"lng_failed_add_not_mutual" = "죄송합니다. 그룹방에서 대화상대방이 나갔을 경우,\n상대 전화번호가 있는 분만 초대가 가능합니다.\n(서로 전화번호가 등록되어져 있어야만 가능)";
|
||||
|
||||
"lng_sure_delete_contact" = "{contact} 님을 주소록에서 \n삭제하시겠습니까?";
|
||||
"lng_sure_delete_history" = "{contact} 님과 관련된 모든 메시지를 \n삭제하시겠습니까?\n\n삭제 하실 경우 취소가 불가능합니다.";
|
||||
"lng_sure_delete_group_history" = "그룹<<{group}>> 방의 모든 메시지 기록을 삭제하시겠습니까?\n\n이 작업은 취소가 불가능합니다.";
|
||||
|
||||
"lng_sure_delete_and_exit" = "그룹 «{group}» 방에서 모든 메시지를 \n삭제하시고 퇴장하시겠습니까?\n\n삭제 하실 경우 취소가 불가능합니다.";
|
||||
|
||||
"lng_message_empty" = "(없음)";
|
||||
"lng_message_empty" = "메시지 없음";
|
||||
"lng_media_unsupported" = "지원하지 않는 미디어";
|
||||
|
||||
"lng_action_add_user" = "{from} 님께서 {user} 님을 초대하셨습니다.";
|
||||
"lng_action_kick_user" = "{from} 님께서 {user} 님을 추방하셨습니다.";
|
||||
@@ -459,12 +480,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_send_button" = "보내기";
|
||||
"lng_message_ph" = "메시지 쓰기";
|
||||
"lng_record_cancel" = "이 영역에서 마우스 클릭을 해제하시면 취소가 됩니다.";
|
||||
"lng_record_cancel" = "이 영역 밖에서 마우스 클릭을 해제하시면 취소가 됩니다.";
|
||||
"lng_empty_history" = "";
|
||||
"lng_willbe_history" = "대화하실 방을 선택해주세요.";
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "회원님";
|
||||
"lng_bot_description" = "봇이 할 수 있는 일은 무엇일까요?";
|
||||
"lng_unblock_button" = "Unblock";
|
||||
|
||||
"lng_bot_start" = "시작";
|
||||
"lng_bot_choose_group" = "그룹 선택";
|
||||
@@ -477,6 +499,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_user_typing" = "{user}님이 입력중입니다.";
|
||||
"lng_users_typing" = "{user}님과 {second_user}님이 입력중입니다.";
|
||||
"lng_many_typing" = "{count:_not_used_|#명이|#명이} 입력중입니다";
|
||||
"lng_send_action_record_video" = "비디오 녹화 중";
|
||||
"lng_user_action_record_video" = "{user}님이 녹화중입니다.";
|
||||
"lng_send_action_upload_video" = "비디오 전송 중";
|
||||
"lng_user_action_upload_video" = "{user}님이 비디오를 전송 중입니다.";
|
||||
"lng_send_action_record_audio" = "오디오 녹음 중";
|
||||
"lng_user_action_record_audio" = "{user}님이 오디오를 녹음 중입니다.";
|
||||
"lng_send_action_upload_audio" = "오디오 전송 중";
|
||||
"lng_user_action_upload_audio" = "{user}님이 오디오를 전송 중입니다.";
|
||||
"lng_send_action_upload_photo" = "사진 전송 중";
|
||||
"lng_user_action_upload_photo" = "{user}님이 사진을 전송 중입니다.";
|
||||
"lng_send_action_upload_file" = "파일을 전송 중";
|
||||
"lng_user_action_upload_file" = "{user}님이 사진을 전송 중입니다.";
|
||||
"lng_send_action_geo_location" = "위치 선택 중";
|
||||
"lng_user_action_geo_location" = "{user}님이 위치를 선택 중입니다.";
|
||||
"lng_send_action_choose_contact" = "연락처 선택 중";
|
||||
"lng_user_action_choose_contact" = "{user}님이 연락처를 선택 중입니다.";
|
||||
"lng_unread_bar" = "{count:_not_used_|#개의 읽지 않은 메시지|#개의 읽지 않은 메시지}";
|
||||
|
||||
"lng_maps_point" = "위치";
|
||||
@@ -603,7 +641,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
||||
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
||||
"lng_new_version_text" = "— 앱내 미디어 재생 기능 향상\n— 버그 수정 및 마이나 기능 향상";
|
||||
"lng_new_version_text" = "— 대화방내 검색 기능\n— 그룹방 대화내용 삭제\n— 메시지가 없는 대화방은 대화목록에서 숨겨짐";
|
||||
|
||||
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_open_from_tray" = "Telegram openen";
|
||||
"lng_minimize_to_tray" = "Minimaliseer naar systeemvak";
|
||||
"lng_quit_from_tray" = "Telegram afsluiten";
|
||||
"lng_tray_icon_text" = "Telegram is nog steeds actief,\nJe kunt dit wijzigen via instellingen.\n\nAls dit icoon verdwijnt van het systeemvak,\nkun je deze terugslepen vanaf de verborgen iconen.";
|
||||
"lng_tray_icon_text" = "Telegram is nog steeds actief, \nje kunt dit wijzigen via instellingen.\nAls dit icoon verdwijnt van het systeemvak,\nkun je deze terugslepen vanaf de verborgen iconen.";
|
||||
|
||||
"lng_month1" = "januari";
|
||||
"lng_month2" = "februari";
|
||||
@@ -69,8 +69,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "Probeer nu";
|
||||
|
||||
"lng_status_service_notifications" = "servicemeldingen";
|
||||
"lng_status_support" = "ondersteuning";
|
||||
"lng_status_bot" = "bot";
|
||||
"lng_status_bot_reads_all" = "toegang tot berichten";
|
||||
"lng_status_bot_reads_all" = "toegang tot berichten";
|
||||
"lng_status_bot_not_reads_all" = "geen toegang tot berichten";
|
||||
"lng_status_offline" = "lang geleden gezien";
|
||||
"lng_status_recently" = "recent gezien";
|
||||
@@ -156,8 +157,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_dlg_new_group_name" = "Groepsnaam";
|
||||
"lng_dlg_create_group" = "Maak";
|
||||
"lng_no_contacts" = "Je hebt geen contacten";
|
||||
"lng_no_chats" = "Hier komen je chats";
|
||||
"lng_contacts_loading" = "Bezig met laden";
|
||||
"lng_contacts_not_found" = "Geen contacten gevonden";
|
||||
"lng_dlg_search_chat" = "Zoek in deze chat";
|
||||
"lng_dlg_search_for_messages" = "Zoek berichten";
|
||||
|
||||
"lng_settings_save" = "Opslaan";
|
||||
"lng_settings_upload" = "Profielfoto instellen";
|
||||
@@ -182,6 +186,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_desktop_notify" = "Desktopmeldingen";
|
||||
"lng_settings_show_name" = "Afzender weergeven";
|
||||
"lng_settings_show_preview" = "Voorvertoning weergeven";
|
||||
"lng_settings_use_windows" = "Windows-berichtgeving gebruiken";
|
||||
"lng_settings_sound_notify" = "Geluiden afspelen";
|
||||
|
||||
"lng_notification_preview" = "Je hebt een nieuw bericht";
|
||||
@@ -289,7 +294,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_bad" = "De hint moet anders zijn dan je wachtwoord.";
|
||||
"lng_cloud_password_email" = "Herstel-e-mailadres invoeren";
|
||||
"lng_cloud_password_bad_email" = "Ongeldig e-mailadres, probeer een andere.";
|
||||
"lng_cloud_password_about" = "Naast de code die je per SMS ontvangt kun je een extra wachtwoord instellen voor als je inlogt op een nieuw apparaat.";
|
||||
"lng_cloud_password_about" = "Dit wachtwoord is nodig als je inlogt vanaf een nieuw apparaat, naast de SMS die je ontvangt.";
|
||||
"lng_cloud_password_about_recover" = "Let op: Echt geen herstel-emailadres\nopgeven voor je wachtwoord?\n\nBij verlies van je wachtwoord ben je\nook de toegang tot Telegram kwijt.";
|
||||
"lng_cloud_password_almost" = "Een bevestigingslink is naar\nhet e-mailadres verstuurd.\n\ntwee-staps-verificatie is actief\nna het klikken van de e-mail-link.";
|
||||
"lng_cloud_password_was_set" = "Twee-staps-verificatie ingeschakeld.";
|
||||
@@ -320,6 +325,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_reset_one_sure" = "Deze sessie beëindigen?";
|
||||
"lng_settings_reset_button" = "Beëindigen";
|
||||
"lng_settings_reset_done" = "Alle andere sessies zijn beëindigd";
|
||||
"lng_settings_ask_question" = "Een vraag stellen";
|
||||
"lng_settings_ask_sure" = "De ondersteuning voor Telegram wordt gedaan door vrijwilligers. We proberen zo snel mogelijk te reageren maar het kan even duren. \n\nBekijk ook de veelgestelde vragen, deze bevat belangrijke tips en antwoorden op de meest gestelde vragen. ";
|
||||
"lng_settings_faq_button" = "Veelgestelde vragen";
|
||||
"lng_settings_ask_ok" = "Vraag";
|
||||
"lng_settings_faq" = "Veelgestelde vragen";
|
||||
"lng_settings_logout" = "Uitloggen";
|
||||
"lng_sure_logout" = "Weet je zeker dat je wilt uitloggen?";
|
||||
|
||||
@@ -339,6 +349,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_topbar_info" = "Info";
|
||||
"lng_profile_about_section" = "Over";
|
||||
"lng_profile_settings_section" = "Instellingen";
|
||||
"lng_profile_actions_section" = "Acties";
|
||||
"lng_profile_bot_settings" = "Instellingen";
|
||||
"lng_profile_bot_help" = "Help";
|
||||
"lng_profile_participants_section" = "Deelnemers";
|
||||
@@ -348,6 +359,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_edit_contact" = "Wijzig";
|
||||
"lng_profile_enable_notifications" = "Meldingen";
|
||||
"lng_profile_clear_history" = "Geschiedenis wissen";
|
||||
"lng_profile_delete_conversation" = "Gesprek verwijderen";
|
||||
"lng_profile_clear_and_exit" = "Verwijder en verlaat";
|
||||
"lng_profile_search_messages" = "Zoek berichten";
|
||||
"lng_profile_block_user" = "Blokkeer gebruiker";
|
||||
"lng_profile_unblock_user" = "Deblokkeer gebruiker";
|
||||
"lng_profile_block_bot" = "Stop en blokkeer bot";
|
||||
"lng_profile_unblock_bot" = "Deblokkeer bot";
|
||||
"lng_profile_send_message" = "Bericht sturen";
|
||||
"lng_profile_share_contact" = "Contact delen";
|
||||
"lng_profile_invite_to_group" = "Groepslid maken";
|
||||
@@ -379,13 +397,16 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "Nieuwe groep";
|
||||
|
||||
"lng_failed_add_participant" = "Gebruiker toevoegen mislukt. Probeer het later nog eens.";
|
||||
"lng_failed_add_not_mutual" = "Sorry, als een persoon verlaat, \nKan alleen een wederzijds\ncontact ze weer toevoegen\n(opgeslagen telefoonnummers).";
|
||||
|
||||
"lng_sure_delete_contact" = "{contact} echt verwijderen uit contacten?";
|
||||
"lng_sure_delete_history" = "Geschiedenis met {contact} echt wissen? \n\nDeze actie kan niet ongedaan worden gemaakt.";
|
||||
"lng_sure_delete_group_history" = "Echt de geschiedenis van «{group}» wissen?\n\nHerstellen is niet mogelijk. ";
|
||||
|
||||
"lng_sure_delete_and_exit" = "Wil je de groep «{group}» verlaten en de geschiedenis wissen?\n\nDeze actie kan niet ongedaan worden gemaakt.";
|
||||
|
||||
"lng_message_empty" = "(leeg)";
|
||||
"lng_message_empty" = "Leeg bericht";
|
||||
"lng_media_unsupported" = "Niet-ondersteunde media";
|
||||
|
||||
"lng_action_add_user" = "{from} heeft {user} toegevoegd";
|
||||
"lng_action_kick_user" = "{from} heeft {user} verwijderd";
|
||||
@@ -465,6 +486,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "Jij";
|
||||
"lng_bot_description" = "Wat kan deze bot? ";
|
||||
"lng_unblock_button" = "Deblokkeer";
|
||||
|
||||
"lng_bot_start" = "Begin";
|
||||
"lng_bot_choose_group" = "Groep kiezen";
|
||||
@@ -477,6 +499,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_user_typing" = "{user} is aan het typen";
|
||||
"lng_users_typing" = "{user} en {second_user} zijn aan het typen";
|
||||
"lng_many_typing" = "{count:_not_used_|# is|# zijn} aan het typen";
|
||||
"lng_send_action_record_video" = "video opnemen";
|
||||
"lng_user_action_record_video" = "{user} neemt video op";
|
||||
"lng_send_action_upload_video" = "video versturen";
|
||||
"lng_user_action_upload_video" = "{user} verstuurt video";
|
||||
"lng_send_action_record_audio" = "geluid opnemen";
|
||||
"lng_user_action_record_audio" = "{user} neemt geluid op";
|
||||
"lng_send_action_upload_audio" = "geluid versturen";
|
||||
"lng_user_action_upload_audio" = "{user} verstuurt geluid";
|
||||
"lng_send_action_upload_photo" = "foto versturen";
|
||||
"lng_user_action_upload_photo" = "{user} verstuurt een foto";
|
||||
"lng_send_action_upload_file" = "bestand versturen";
|
||||
"lng_user_action_upload_file" = "{user} verstuurt een bestand";
|
||||
"lng_send_action_geo_location" = "locatie kiezen";
|
||||
"lng_user_action_geo_location" = "{user} kiest een locatie";
|
||||
"lng_send_action_choose_contact" = "contact kiezen";
|
||||
"lng_user_action_choose_contact" = "{user} kiest een contact";
|
||||
"lng_unread_bar" = "{count:_not_used_|# ongelezen bericht|# ongelezen berichten}";
|
||||
|
||||
"lng_maps_point" = "Locatie";
|
||||
@@ -603,7 +641,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
|
||||
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
||||
"lng_new_version_text" = "— Media afspelen binnen de app verbeterd\n— Probleemoplossing en kleine verbeteringen";
|
||||
"lng_new_version_text" = "— Zoek berichten binnen gesprekken\n— Berichtengeschiedenis van groepen wissen\n— Contacten zonder berichten zijn verborgen in de gesprekslijst";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_open_from_tray" = "Abrir Telegram";
|
||||
"lng_minimize_to_tray" = "Minimizar";
|
||||
"lng_quit_from_tray" = "Sair do Telegram";
|
||||
"lng_tray_icon_text" = "Telegram ainda está sendo executado,\nvocê pode mudar isso nas configurações.\n\nSe este ícone desaparecer de sua bandeja,\nvocê pode arrastar de volta dos ícones ocultos.";
|
||||
"lng_tray_icon_text" = "Telegram ainda está sendo executado,\nvocê pode mudar isso nas configurações.\nSe este ícone desaparecer de sua bandeja,\nvocê pode arrastar de volta dos ícones ";
|
||||
|
||||
"lng_month1" = "Janeiro";
|
||||
"lng_month2" = "Fevereiro";
|
||||
@@ -69,6 +69,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "Tentar agora";
|
||||
|
||||
"lng_status_service_notifications" = "notificações de serviço";
|
||||
"lng_status_support" = "suporte";
|
||||
"lng_status_bot" = "bot";
|
||||
"lng_status_bot_reads_all" = "tem acesso as mensagens";
|
||||
"lng_status_bot_not_reads_all" = "não tem acesso as mensagens";
|
||||
@@ -156,8 +157,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_dlg_new_group_name" = "Nome do grupo";
|
||||
"lng_dlg_create_group" = "Criar";
|
||||
"lng_no_contacts" = "Você não possui contatos";
|
||||
"lng_no_chats" = "Seus chats estarão aqui";
|
||||
"lng_contacts_loading" = "Carregando..";
|
||||
"lng_contacts_not_found" = "Nenhum contato encontrado";
|
||||
"lng_dlg_search_chat" = "Buscar nesse chat";
|
||||
"lng_dlg_search_for_messages" = "Buscar por mensagens";
|
||||
|
||||
"lng_settings_save" = "Salvar";
|
||||
"lng_settings_upload" = "Definir Foto de Perfil";
|
||||
@@ -182,6 +186,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_desktop_notify" = "Notificações na área de trabalho";
|
||||
"lng_settings_show_name" = "Mostrar nome de quem enviou";
|
||||
"lng_settings_show_preview" = "Mostrar pré-visualização da mensagem";
|
||||
"lng_settings_use_windows" = "Usar notificações do Windows";
|
||||
"lng_settings_sound_notify" = "Tocar som";
|
||||
|
||||
"lng_notification_preview" = "Você tem uma nova mensagem";
|
||||
@@ -320,6 +325,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_reset_one_sure" = "Você deseja terminar essa sessão?";
|
||||
"lng_settings_reset_button" = "Encerrar";
|
||||
"lng_settings_reset_done" = "Outras sessões encerradas";
|
||||
"lng_settings_ask_question" = "Fazer uma Pergunta";
|
||||
"lng_settings_ask_sure" = "Entenda que o suporte do Telegram é feito por voluntários. Tentaremos responder o mais rápido possível, mas poderemos demorar um pouco.\n\nPor favor verifique a página de Perguntas Frequentes do Telegram: há dicas e respostas para a maioria das perguntas.";
|
||||
"lng_settings_faq_button" = "Perguntas Frequentes";
|
||||
"lng_settings_ask_ok" = "Perguntar";
|
||||
"lng_settings_faq" = "Perguntas Frequentes";
|
||||
"lng_settings_logout" = "Sair";
|
||||
"lng_sure_logout" = "Tem certeza que deseja sair?";
|
||||
|
||||
@@ -339,6 +349,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_topbar_info" = "Info";
|
||||
"lng_profile_about_section" = "Sobre";
|
||||
"lng_profile_settings_section" = "Configurações";
|
||||
"lng_profile_actions_section" = "Ações";
|
||||
"lng_profile_bot_settings" = "Configurações";
|
||||
"lng_profile_bot_help" = "Ajuda";
|
||||
"lng_profile_participants_section" = "Membros";
|
||||
@@ -348,6 +359,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_edit_contact" = "Editar";
|
||||
"lng_profile_enable_notifications" = "Notificações";
|
||||
"lng_profile_clear_history" = "Limpar histórico";
|
||||
"lng_profile_delete_conversation" = "Apagar conversa";
|
||||
"lng_profile_clear_and_exit" = "Apagar e sair";
|
||||
"lng_profile_search_messages" = "Buscar mensagens";
|
||||
"lng_profile_block_user" = "Bloquear usuário";
|
||||
"lng_profile_unblock_user" = "Desbloquear usuário";
|
||||
"lng_profile_block_bot" = "Parar e bloquear o bot";
|
||||
"lng_profile_unblock_bot" = "Desbloquear bot";
|
||||
"lng_profile_send_message" = "Enviar Mensagem";
|
||||
"lng_profile_share_contact" = "Compartilhar";
|
||||
"lng_profile_invite_to_group" = "Adicionar ao Grupo";
|
||||
@@ -379,13 +397,16 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "Novo Grupo";
|
||||
|
||||
"lng_failed_add_participant" = "Não foi possível adicionar o usuário. Tente novamente mais tarde.";
|
||||
"lng_failed_add_not_mutual" = "Desculpe, se uma pessoa deixou o\ngrupo, apenas um contato mútuo pode\ncolocá-la de volta (eles precisam do seu \ncontato no telefone e você o deles)";
|
||||
|
||||
"lng_sure_delete_contact" = "Você tem certeza que deseja remover {contact} da sua lista de contatos?";
|
||||
"lng_sure_delete_history" = "Você tem certeza que deseja apagar todo o seu histórico de mensagens com {contact}?\n\nEssa ação não pode ser desfeita.";
|
||||
"lng_sure_delete_group_history" = "Você tem certeza que deseja apagar todo o histórico de «{group}»?\n\nEssa ação não pode ser desfeita.";
|
||||
|
||||
"lng_sure_delete_and_exit" = "Você tem certeza que deseja apagar todo o seu histórico de mensagens e deixar «{group}»?\n\nEssa ação não pode ser desfeita.";
|
||||
|
||||
"lng_message_empty" = "(vazio)";
|
||||
"lng_message_empty" = "Mensagem Vazia";
|
||||
"lng_media_unsupported" = "Mídia Não-Suportada";
|
||||
|
||||
"lng_action_add_user" = "{from} adicionou {user}";
|
||||
"lng_action_kick_user" = "{from} removeu {user}";
|
||||
@@ -465,6 +486,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "Você";
|
||||
"lng_bot_description" = "O que esse bot pode fazer?";
|
||||
"lng_unblock_button" = "Desbloquear";
|
||||
|
||||
"lng_bot_start" = "Iniciar";
|
||||
"lng_bot_choose_group" = "Escolher Grupo";
|
||||
@@ -477,6 +499,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_user_typing" = "{user} está escrevendo";
|
||||
"lng_users_typing" = "{user} e {second_user} estão escrevendo";
|
||||
"lng_many_typing" = "{count:_not_used_|# está|# estão} escrevendo";
|
||||
"lng_send_action_record_video" = "gravando vídeo";
|
||||
"lng_user_action_record_video" = "{user} está gravando vídeo";
|
||||
"lng_send_action_upload_video" = "enviando vídeo";
|
||||
"lng_user_action_upload_video" = "{user} está enviando vídeo";
|
||||
"lng_send_action_record_audio" = "gravando áudio";
|
||||
"lng_user_action_record_audio" = "{user} está gravando áudio";
|
||||
"lng_send_action_upload_audio" = "enviando áudio";
|
||||
"lng_user_action_upload_audio" = "{user} está gravando áudio";
|
||||
"lng_send_action_upload_photo" = "enviando foto";
|
||||
"lng_user_action_upload_photo" = "{user} está enviando foto";
|
||||
"lng_send_action_upload_file" = "enviando arquivo";
|
||||
"lng_user_action_upload_file" = "{user} está enviando arquivo";
|
||||
"lng_send_action_geo_location" = "escolhendo local";
|
||||
"lng_user_action_geo_location" = "{user} está escolhendo local";
|
||||
"lng_send_action_choose_contact" = "escolhendo contato";
|
||||
"lng_user_action_choose_contact" = "{user} está escolhendo contato";
|
||||
"lng_unread_bar" = "{count:_not_used_|# mensagem não lida|# mensagens não lidas}";
|
||||
|
||||
"lng_maps_point" = "Localização";
|
||||
@@ -603,7 +641,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
|
||||
"lng_new_version_minor" = "— Resolução de bugs e outras menores melhorias";
|
||||
"lng_new_version_text" = "— Reprodução de mídia no app melhorada\n— Resolução de bugs e menores melhorias";
|
||||
"lng_new_version_text" = "— Buscar mensagens em uma conversa\n— Limpar histórico de mensagens em grupos\n— Contatos sem mensagens estão ocultos da lista de conversas";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
||||
|
||||
|
||||
@@ -78,12 +78,15 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||
type = ToPrepareDocument;
|
||||
}
|
||||
}
|
||||
if (type == ToPrepareDocument) {
|
||||
mime = mimeTypeForFile(info).name();
|
||||
}
|
||||
if (type != ToPrepareAuto && info.size() < MaxUploadPhotoSize) {
|
||||
bool opaque = (mime != stickerMime);
|
||||
img = App::readImage(file, 0, opaque, &animated);
|
||||
if (animated) {
|
||||
type = ToPrepareDocument;
|
||||
}
|
||||
}
|
||||
if (type == ToPrepareDocument) {
|
||||
mime = mimeTypeForFile(info).name();
|
||||
}
|
||||
filename = info.fileName();
|
||||
filesize = info.size();
|
||||
@@ -221,7 +224,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||
}
|
||||
if (!filesize) filesize = jpeg.size();
|
||||
|
||||
photo = MTP_photo(MTP_long(id), MTP_long(0), MTP_int(user), MTP_int(unixtime()), MTP_geoPointEmpty(), MTP_vector<MTPPhotoSize>(photoSizes));
|
||||
photo = MTP_photo(MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_vector<MTPPhotoSize>(photoSizes));
|
||||
|
||||
thumbId = id;
|
||||
} else if ((type == ToPrepareVideo || type == ToPrepareDocument) && !img.isNull() && !isSong) {
|
||||
@@ -254,7 +257,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||
if (type == ToPrepareDocument) {
|
||||
document = MTP_document(MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_string(mime), MTP_int(filesize), thumb, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
|
||||
} else if (type == ToPrepareAudio) {
|
||||
audio = MTP_audio(MTP_long(id), MTP_long(0), MTP_int(user), MTP_int(unixtime()), MTP_int(duration), MTP_string(mime), MTP_int(filesize), MTP_int(MTP::maindc()));
|
||||
audio = MTP_audio(MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_int(duration), MTP_string(mime), MTP_int(filesize), MTP_int(MTP::maindc()));
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "localstorage.h"
|
||||
|
||||
#include "mainwidget.h"
|
||||
#include "window.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace {
|
||||
@@ -505,6 +507,7 @@ namespace {
|
||||
lskUserSettings = 0x09, // no data
|
||||
lskRecentHashtags = 0x0a, // no data
|
||||
lskStickers = 0x0b, // no data
|
||||
lskSavedPeers = 0x0c, // no data
|
||||
};
|
||||
|
||||
typedef QMap<PeerId, FileKey> DraftsMap;
|
||||
@@ -530,13 +533,15 @@ namespace {
|
||||
FileKey _recentHashtagsKey = 0;
|
||||
bool _recentHashtagsWereRead = false;
|
||||
|
||||
FileKey _savedPeersKey = 0;
|
||||
|
||||
typedef QPair<FileKey, qint32> FileDesc; // file, size
|
||||
typedef QMap<StorageKey, FileDesc> StorageMap;
|
||||
StorageMap _imagesMap, _stickerImagesMap, _audiosMap;
|
||||
int32 _storageImagesSize = 0, _storageStickersSize = 0, _storageAudiosSize = 0;
|
||||
|
||||
bool _mapChanged = false;
|
||||
int32 _oldMapVersion = 0;
|
||||
int32 _oldMapVersion = 0, _oldSettingsVersion = 0;
|
||||
|
||||
enum WriteMapWhen {
|
||||
WriteMapNow,
|
||||
@@ -733,6 +738,15 @@ namespace {
|
||||
cSetDesktopNotify(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiWindowsNotifications: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetWindowsNotifications(v == 1);
|
||||
cSetCustomNotifies((App::wnd() ? App::wnd()->psHasNativeNotifications() : true) && !cWindowsNotifications());
|
||||
} break;
|
||||
|
||||
case dbiWorkMode: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
@@ -1265,7 +1279,7 @@ namespace {
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
|
||||
uint32 size = 12 * (sizeof(quint32) + sizeof(qint32));
|
||||
uint32 size = 13 * (sizeof(quint32) + sizeof(qint32));
|
||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
||||
@@ -1281,6 +1295,7 @@ namespace {
|
||||
data.stream << quint32(dbiSoundNotify) << qint32(cSoundNotify());
|
||||
data.stream << quint32(dbiDesktopNotify) << qint32(cDesktopNotify());
|
||||
data.stream << quint32(dbiNotifyView) << qint32(cNotifyView());
|
||||
data.stream << quint32(dbiWindowsNotifications) << qint32(cWindowsNotifications());
|
||||
data.stream << quint32(dbiAskDownloadPath) << qint32(cAskDownloadPath());
|
||||
data.stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage());
|
||||
@@ -1432,7 +1447,7 @@ namespace {
|
||||
DraftsNotReadMap draftsNotReadMap;
|
||||
StorageMap imagesMap, stickerImagesMap, audiosMap;
|
||||
qint64 storageImagesSize = 0, storageStickersSize = 0, storageAudiosSize = 0;
|
||||
quint64 locationsKey = 0, recentStickersKeyOld = 0, stickersKey = 0, backgroundKey = 0, userSettingsKey = 0, recentHashtagsKey = 0;
|
||||
quint64 locationsKey = 0, recentStickersKeyOld = 0, stickersKey = 0, backgroundKey = 0, userSettingsKey = 0, recentHashtagsKey = 0, savedPeersKey = 0;
|
||||
while (!map.stream.atEnd()) {
|
||||
quint32 keyType;
|
||||
map.stream >> keyType;
|
||||
@@ -1512,6 +1527,9 @@ namespace {
|
||||
case lskStickers: {
|
||||
map.stream >> stickersKey;
|
||||
} break;
|
||||
case lskSavedPeers: {
|
||||
map.stream >> savedPeersKey;
|
||||
} break;
|
||||
default:
|
||||
LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType));
|
||||
return Local::ReadMapFailed;
|
||||
@@ -1535,6 +1553,7 @@ namespace {
|
||||
_locationsKey = locationsKey;
|
||||
_recentStickersKeyOld = recentStickersKeyOld;
|
||||
_stickersKey = stickersKey;
|
||||
_savedPeersKey = savedPeersKey;
|
||||
_backgroundKey = backgroundKey;
|
||||
_userSettingsKey = userSettingsKey;
|
||||
_recentHashtagsKey = recentHashtagsKey;
|
||||
@@ -1554,6 +1573,9 @@ namespace {
|
||||
_readMtpData();
|
||||
|
||||
LOG(("Map read time: %1").arg(getms() - ms));
|
||||
if (_oldSettingsVersion < AppVersion) {
|
||||
Local::writeSettings();
|
||||
}
|
||||
return Local::ReadMapDone;
|
||||
}
|
||||
|
||||
@@ -1599,6 +1621,7 @@ namespace {
|
||||
if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||
if (_recentStickersKeyOld) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||
if (_stickersKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||
if (_savedPeersKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||
if (_backgroundKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||
if (_userSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||
if (_recentHashtagsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||
@@ -1642,6 +1665,9 @@ namespace {
|
||||
if (_stickersKey) {
|
||||
mapData.stream << quint32(lskStickers) << quint64(_stickersKey);
|
||||
}
|
||||
if (_savedPeersKey) {
|
||||
mapData.stream << quint32(lskSavedPeers) << quint64(_savedPeersKey);
|
||||
}
|
||||
if (_backgroundKey) {
|
||||
mapData.stream << quint32(lskBackground) << quint64(_backgroundKey);
|
||||
}
|
||||
@@ -1797,6 +1823,7 @@ namespace Local {
|
||||
cSetDcOptions(dcOpts);
|
||||
}
|
||||
|
||||
_oldSettingsVersion = settingsData.version;
|
||||
_settingsSalt = salt;
|
||||
}
|
||||
|
||||
@@ -1900,7 +1927,7 @@ namespace Local {
|
||||
_draftsNotReadMap.clear();
|
||||
_stickerImagesMap.clear();
|
||||
_audiosMap.clear();
|
||||
_locationsKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = 0;
|
||||
_locationsKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0;
|
||||
_mapChanged = true;
|
||||
_writeMap(WriteMapNow);
|
||||
|
||||
@@ -1939,6 +1966,10 @@ namespace Local {
|
||||
return _oldMapVersion;
|
||||
}
|
||||
|
||||
int32 oldSettingsVersion() {
|
||||
return _oldSettingsVersion;
|
||||
}
|
||||
|
||||
void writeDraft(const PeerId &peer, const MessageDraft &draft) {
|
||||
if (!_working()) return;
|
||||
|
||||
@@ -2293,6 +2324,23 @@ namespace Local {
|
||||
return _storageAudiosSize;
|
||||
}
|
||||
|
||||
void _writeStorageImageLocation(QDataStream &stream, const StorageImageLocation &loc) {
|
||||
stream << qint32(loc.width) << qint32(loc.height);
|
||||
stream << qint32(loc.dc) << quint64(loc.volume) << qint32(loc.local) << quint64(loc.secret);
|
||||
}
|
||||
|
||||
uint32 _storageImageLocationSize() {
|
||||
// width + height + dc + volume + local + secret
|
||||
return sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint64) + sizeof(qint32) + sizeof(quint64);
|
||||
}
|
||||
|
||||
StorageImageLocation _readStorageImageLocation(FileReadDescriptor &from) {
|
||||
qint32 thumbWidth, thumbHeight, thumbDc, thumbLocal;
|
||||
quint64 thumbVolume, thumbSecret;
|
||||
from.stream >> thumbWidth >> thumbHeight >> thumbDc >> thumbVolume >> thumbLocal >> thumbSecret;
|
||||
return StorageImageLocation(thumbWidth, thumbHeight, thumbDc, thumbVolume, thumbLocal, thumbSecret);
|
||||
}
|
||||
|
||||
void _writeStickerSet(QDataStream &stream, uint64 setId) {
|
||||
StickerSets::const_iterator it = cStickerSets().constFind(setId);
|
||||
if (it == cStickerSets().cend()) return;
|
||||
@@ -2321,8 +2369,7 @@ namespace Local {
|
||||
stream << qint32(StickerSetTypeEmpty);
|
||||
} break;
|
||||
}
|
||||
const StorageImageLocation &loc(doc->sticker()->loc);
|
||||
stream << qint32(loc.width) << qint32(loc.height) << qint32(loc.dc) << quint64(loc.volume) << qint32(loc.local) << quint64(loc.secret);
|
||||
_writeStorageImageLocation(stream, doc->sticker()->loc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2358,8 +2405,8 @@ namespace Local {
|
||||
// id + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + alt + type-of-set
|
||||
size += sizeof(quint64) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(doc->sticker()->alt) + sizeof(qint32);
|
||||
|
||||
// thumb-width + thumb-height + thumb-dc + thumb-volume + thumb-local + thumb-secret
|
||||
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(quint64) + sizeof(qint32) + sizeof(quint64);
|
||||
// loc
|
||||
size += _storageImageLocationSize();
|
||||
}
|
||||
++setsCount;
|
||||
}
|
||||
@@ -2519,9 +2566,7 @@ namespace Local {
|
||||
qint32 date, dc, size, width, height, type, typeOfSet;
|
||||
stickers.stream >> id >> access >> date >> name >> mime >> dc >> size >> width >> height >> type >> alt >> typeOfSet;
|
||||
|
||||
qint32 thumbWidth, thumbHeight, thumbDc, thumbLocal;
|
||||
quint64 thumbVolume, thumbSecret;
|
||||
stickers.stream >> thumbWidth >> thumbHeight >> thumbDc >> thumbVolume >> thumbLocal >> thumbSecret;
|
||||
StorageImageLocation thumb(_readStorageImageLocation(stickers));
|
||||
|
||||
if (read.contains(id)) continue;
|
||||
read.insert(id, true);
|
||||
@@ -2552,7 +2597,6 @@ namespace Local {
|
||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
||||
}
|
||||
|
||||
StorageImageLocation thumb(thumbWidth, thumbHeight, thumbDc, thumbVolume, thumbLocal, thumbSecret);
|
||||
DocumentData *doc = App::documentSet(id, 0, access, date, attributes, mime, thumb.dc ? ImagePtr(thumb) : ImagePtr(), dc, size, thumb);
|
||||
if (!doc->sticker()) continue;
|
||||
|
||||
@@ -2705,6 +2749,190 @@ namespace Local {
|
||||
cSetRecentSearchHashtags(search);
|
||||
}
|
||||
|
||||
uint32 _peerSize(PeerData *peer) {
|
||||
uint32 result = sizeof(quint64) + sizeof(quint64) + _storageImageLocationSize();
|
||||
if (peer->chat) {
|
||||
ChatData *chat = peer->asChat();
|
||||
|
||||
// name + count + date + version + admin + forbidden + left + invitationUrl
|
||||
result += _stringSize(chat->name) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(chat->invitationUrl);
|
||||
} else {
|
||||
UserData *user = peer->asUser();
|
||||
|
||||
// first + last + phone + username + access + onlineTill + contact + botInfoVersion
|
||||
result += _stringSize(user->firstName) + _stringSize(user->lastName) + _stringSize(user->phone) + _stringSize(user->username) + sizeof(quint64) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void _writePeer(QDataStream &stream, PeerData *peer) {
|
||||
stream << quint64(peer->id) << quint64(peer->photoId);
|
||||
_writeStorageImageLocation(stream, peer->photoLoc);
|
||||
if (peer->chat) {
|
||||
ChatData *chat = peer->asChat();
|
||||
|
||||
stream << chat->name << qint32(chat->count) << qint32(chat->date) << qint32(chat->version) << qint32(chat->admin);
|
||||
stream << qint32(chat->forbidden ? 1 : 0) << qint32(chat->left ? 1 : 0) << chat->invitationUrl;
|
||||
} else {
|
||||
UserData *user = peer->asUser();
|
||||
|
||||
stream << user->firstName << user->lastName << user->phone << user->username << quint64(user->access) << qint32(user->onlineTill) << qint32(user->contact) << qint32(user->botInfo ? user->botInfo->version : -1);
|
||||
}
|
||||
}
|
||||
|
||||
PeerData *_readPeer(FileReadDescriptor &from) {
|
||||
PeerData *result = 0;
|
||||
quint64 peerId = 0, photoId = 0;
|
||||
from.stream >> peerId >> photoId;
|
||||
|
||||
StorageImageLocation photoLoc(_readStorageImageLocation(from));
|
||||
|
||||
result = App::peer(peerId);
|
||||
result->loaded = true;
|
||||
if (result->chat) {
|
||||
ChatData *chat = result->asChat();
|
||||
|
||||
QString name, invitationUrl;
|
||||
qint32 count, date, version, admin, forbidden, left;
|
||||
from.stream >> name >> count >> date >> version >> admin >> forbidden >> left >> invitationUrl;
|
||||
|
||||
chat->updateName(name, QString(), QString());
|
||||
chat->count = count;
|
||||
chat->date = date;
|
||||
chat->version = version;
|
||||
chat->admin = admin;
|
||||
chat->forbidden = (forbidden == 1);
|
||||
chat->left = (left == 1);
|
||||
chat->invitationUrl = invitationUrl;
|
||||
|
||||
chat->input = MTP_inputPeerChat(MTP_int(App::chatFromPeer(chat->id)));
|
||||
|
||||
chat->photo = photoLoc.isNull() ? ImagePtr(chatDefPhoto(chat->colorIndex)) : ImagePtr(photoLoc);
|
||||
} else {
|
||||
UserData *user = result->asUser();
|
||||
|
||||
QString first, last, phone, username;
|
||||
quint64 access;
|
||||
qint32 onlineTill, contact, botInfoVersion;
|
||||
from.stream >> first >> last >> phone >> username >> access >> onlineTill >> contact >> botInfoVersion;
|
||||
|
||||
bool showPhone = !isServiceUser(user->id) && (App::userFromPeer(user->id) != MTP::authedId()) && (contact <= 0);
|
||||
QString pname = (showPhone && !phone.isEmpty()) ? App::formatPhone(phone) : QString();
|
||||
|
||||
user->setName(first, last, pname, username);
|
||||
|
||||
user->access = access;
|
||||
user->onlineTill = onlineTill;
|
||||
user->contact = contact;
|
||||
user->setBotInfoVersion(botInfoVersion);
|
||||
|
||||
if (App::userFromPeer(user->id) == MTP::authedId()) {
|
||||
user->input = MTP_inputPeerSelf();
|
||||
user->inputUser = MTP_inputUserSelf();
|
||||
} else {
|
||||
user->input = MTP_inputPeerUser(MTP_int(App::userFromPeer(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
|
||||
user->inputUser = MTP_inputUser(MTP_int(App::userFromPeer(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
|
||||
}
|
||||
|
||||
user->photo = photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc);
|
||||
}
|
||||
App::markPeerUpdated(result);
|
||||
emit App::main()->peerPhotoChanged(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void writeSavedPeers() {
|
||||
if (!_working()) return;
|
||||
|
||||
const SavedPeers &saved(cSavedPeers());
|
||||
if (saved.isEmpty()) {
|
||||
if (_savedPeersKey) {
|
||||
clearKey(_savedPeersKey);
|
||||
_savedPeersKey = 0;
|
||||
_mapChanged = true;
|
||||
}
|
||||
_writeMap();
|
||||
} else {
|
||||
if (!_savedPeersKey) {
|
||||
_savedPeersKey = genKey();
|
||||
_mapChanged = true;
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
quint32 size = sizeof(quint32);
|
||||
for (SavedPeers::const_iterator i = saved.cbegin(); i != saved.cend(); ++i) {
|
||||
size += _peerSize(i.key()) + _dateTimeSize();
|
||||
}
|
||||
|
||||
EncryptedDescriptor data(size);
|
||||
data.stream << quint32(saved.size());
|
||||
for (SavedPeers::const_iterator i = saved.cbegin(); i != saved.cend(); ++i) {
|
||||
_writePeer(data.stream, i.key());
|
||||
data.stream << i.value();
|
||||
}
|
||||
|
||||
FileWriteDescriptor file(_savedPeersKey);
|
||||
file.writeEncrypted(data);
|
||||
}
|
||||
}
|
||||
|
||||
void readSavedPeers() {
|
||||
if (!_savedPeersKey) return;
|
||||
|
||||
FileReadDescriptor saved;
|
||||
if (!readEncryptedFile(saved, _savedPeersKey)) {
|
||||
clearKey(_savedPeersKey);
|
||||
_savedPeersKey = 0;
|
||||
_writeMap();
|
||||
return;
|
||||
}
|
||||
|
||||
quint32 count = 0;
|
||||
saved.stream >> count;
|
||||
cRefSavedPeers().clear();
|
||||
cRefSavedPeersByTime().clear();
|
||||
QList<PeerData*> peers;
|
||||
peers.reserve(count);
|
||||
for (uint32 i = 0; i < count; ++i) {
|
||||
PeerData *peer = _readPeer(saved);
|
||||
if (!peer) break;
|
||||
|
||||
QDateTime t;
|
||||
saved.stream >> t;
|
||||
|
||||
cRefSavedPeers().insert(peer, t);
|
||||
cRefSavedPeersByTime().insert(t, peer);
|
||||
peers.push_back(peer);
|
||||
}
|
||||
App::emitPeerUpdated();
|
||||
App::api()->requestPeers(peers);
|
||||
}
|
||||
|
||||
void addSavedPeer(PeerData *peer, const QDateTime &position) {
|
||||
SavedPeers &savedPeers(cRefSavedPeers());
|
||||
SavedPeers::iterator i = savedPeers.find(peer);
|
||||
if (i == savedPeers.cend()) {
|
||||
savedPeers.insert(peer, position);
|
||||
} else if (i.value() != position) {
|
||||
cRefSavedPeersByTime().remove(i.value(), peer);
|
||||
i.value() = position;
|
||||
cRefSavedPeersByTime().insert(i.value(), peer);
|
||||
}
|
||||
writeSavedPeers();
|
||||
}
|
||||
|
||||
void removeSavedPeer(PeerData *peer) {
|
||||
SavedPeers &savedPeers(cRefSavedPeers());
|
||||
if (savedPeers.isEmpty()) return;
|
||||
|
||||
SavedPeers::iterator i = savedPeers.find(peer);
|
||||
if (i != savedPeers.cend()) {
|
||||
cRefSavedPeersByTime().remove(i.value(), peer);
|
||||
savedPeers.erase(i);
|
||||
|
||||
writeSavedPeers();
|
||||
}
|
||||
}
|
||||
|
||||
struct ClearManagerData {
|
||||
QThread *thread;
|
||||
StorageMap images, stickers, audios;
|
||||
@@ -2764,6 +2992,10 @@ namespace Local {
|
||||
_recentHashtagsKey = 0;
|
||||
_mapChanged = true;
|
||||
}
|
||||
if (_savedPeersKey) {
|
||||
_savedPeersKey = 0;
|
||||
_mapChanged = true;
|
||||
}
|
||||
_writeMap();
|
||||
} else {
|
||||
if (task & ClearManagerStorage) {
|
||||
|
||||
@@ -100,6 +100,8 @@ namespace Local {
|
||||
ReadMapState readMap(const QByteArray &pass);
|
||||
int32 oldMapVersion();
|
||||
|
||||
int32 oldSettingsVersion();
|
||||
|
||||
struct MessageDraft {
|
||||
MessageDraft(MsgId replyTo = 0, QString text = QString(), bool previewCancelled = false) : replyTo(replyTo), text(text), previewCancelled(previewCancelled) {
|
||||
}
|
||||
@@ -141,4 +143,8 @@ namespace Local {
|
||||
void writeRecentHashtags();
|
||||
void readRecentHashtags();
|
||||
|
||||
void addSavedPeer(PeerData *peer, const QDateTime &position);
|
||||
void removeSavedPeer(PeerData *peer);
|
||||
void readSavedPeers();
|
||||
|
||||
};
|
||||
|
||||
@@ -39,6 +39,9 @@ int main(int argc, char *argv[]) {
|
||||
logsInit();
|
||||
|
||||
Local::readSettings();
|
||||
if (Local::oldSettingsVersion() < AppVersion) {
|
||||
psNewVersion();
|
||||
}
|
||||
if (cFromAutoStart() && !cAutoStart()) {
|
||||
psAutoStart(false, true);
|
||||
Local::stop();
|
||||
|
||||
@@ -122,7 +122,7 @@ void TopBarWidget::onDeleteAndExitSure() {
|
||||
if (c) {
|
||||
App::main()->showDialogs();
|
||||
App::wnd()->hideLayer();
|
||||
MTP::send(MTPmessages_DeleteChatUser(MTP_int(p->id & 0xFFFFFFFF), App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistory, p), App::main()->rpcFail(&MainWidget::leaveChatFailed, p));
|
||||
MTP::send(MTPmessages_DeleteChatUser(MTP_int(p->id & 0xFFFFFFFF), App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, p), App::main()->rpcFail(&MainWidget::leaveChatFailed, p));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -738,20 +738,20 @@ bool MainWidget::leaveChatFailed(PeerData *peer, const RPCError &error) {
|
||||
showDialogs();
|
||||
}
|
||||
dialogs.removePeer(peer);
|
||||
App::histories().remove(peer->id);
|
||||
App::history(peer->id)->clear();
|
||||
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWidget::deleteHistory(PeerData *peer, const MTPUpdates &updates) {
|
||||
void MainWidget::deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates) {
|
||||
sentUpdatesReceived(updates);
|
||||
if ((profile && profile->peer() == peer) || (overview && overview->peer() == peer) || _stack.contains(peer) || history.peer() == peer) {
|
||||
showDialogs();
|
||||
}
|
||||
dialogs.removePeer(peer);
|
||||
App::histories().remove(peer->id);
|
||||
App::history(peer->id)->clear();
|
||||
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
|
||||
}
|
||||
|
||||
@@ -776,26 +776,23 @@ void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result)
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
void MainWidget::deleteHistoryAndContact(UserData *user, const MTPcontacts_Link &result) {
|
||||
const MTPDcontacts_link &d(result.c_contacts_link());
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser), false);
|
||||
App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link, false);
|
||||
App::emitPeerUpdated();
|
||||
|
||||
if ((profile && profile->peer() == user) || (overview && overview->peer() == user) || _stack.contains(user) || history.peer() == user) {
|
||||
showDialogs();
|
||||
}
|
||||
dialogs.removePeer(user);
|
||||
MTP::send(MTPmessages_DeleteHistory(user->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, (PeerData*)user));
|
||||
void MainWidget::deleteConversation(PeerData *peer) {
|
||||
dialogs.removePeer(peer);
|
||||
History *h = App::history(peer->id);
|
||||
h->clear();
|
||||
h->newLoaded = h->oldLoaded = true;
|
||||
showDialogs();
|
||||
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
|
||||
}
|
||||
|
||||
void MainWidget::clearHistory(PeerData *peer) {
|
||||
if (!peer->chat && peer->asUser()->contact <= 0) {
|
||||
dialogs.removePeer(peer->asUser());
|
||||
History *h = App::history(peer->id);
|
||||
if (h->lastMsg) {
|
||||
Local::addSavedPeer(h->peer, h->lastMsg->date);
|
||||
}
|
||||
dialogsToUp();
|
||||
dialogs.update();
|
||||
App::history(peer->id)->clear();
|
||||
h->clear();
|
||||
h->newLoaded = h->oldLoaded = true;
|
||||
showPeerHistory(peer->id, ShowAtUnreadMsgId);
|
||||
MTP::send(MTPmessages_DeleteHistory(peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, peer));
|
||||
}
|
||||
|
||||
@@ -816,6 +813,8 @@ bool MainWidget::addParticipantFail(UserData *user, const RPCError &error) {
|
||||
|
||||
QString text = lang(lng_failed_add_participant);
|
||||
if (error.type() == "USER_LEFT_CHAT") { // trying to return banned user to his group
|
||||
} else if (error.type() == "USER_NOT_MUTUAL_CONTACT") { // trying to return user who does not have me in contacts
|
||||
text = lang(lng_failed_add_not_mutual);
|
||||
} else if (error.type() == "USER_ALREADY_PARTICIPANT" && user->botInfo) {
|
||||
text = lang(lng_bot_already_in_group);
|
||||
}
|
||||
@@ -859,7 +858,12 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
|
||||
if ((profile && profile->peer() == peer) || (overview && overview->peer() == peer) || _stack.contains(peer) || history.peer() == peer) {
|
||||
showDialogs();
|
||||
}
|
||||
dialogs.removePeer(peer);
|
||||
if (peer->chat && peer->asChat()->left) {
|
||||
dialogs.removePeer(peer);
|
||||
} else {
|
||||
History *h = App::historyLoaded(peer->id);
|
||||
if (h) Local::addSavedPeer(peer, h->lastMsgDate);
|
||||
}
|
||||
} else {
|
||||
History *h = App::historyLoaded(peer->id);
|
||||
if (!h->lastMsg) {
|
||||
@@ -1002,8 +1006,8 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
|
||||
WebPageData *page = App::webPage(webPageId);
|
||||
media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill)));
|
||||
}
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, MTPnullEntities));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, MTPnullEntities), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
|
||||
finishForwarding(hist);
|
||||
@@ -1730,7 +1734,7 @@ void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &
|
||||
QString sendingText, leftText = msg;
|
||||
HistoryItem *item = 0;
|
||||
while (textSplit(sendingText, leftText, MaxMessageSize)) {
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup), unread ? 1 : 2);
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, MTPnullEntities), unread ? 1 : 2);
|
||||
}
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
@@ -2530,6 +2534,16 @@ void MainWidget::onPeerShown(PeerData *peer) {
|
||||
if (animating()) _topBar.hide();
|
||||
}
|
||||
|
||||
void MainWidget::searchInPeer(PeerData *peer) {
|
||||
dialogs.searchInPeer(peer);
|
||||
if (cWideMode()) {
|
||||
dialogs.activate();
|
||||
} else {
|
||||
dialogsToUp();
|
||||
showDialogs();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::onUpdateNotifySettings() {
|
||||
if (this != App::main()) return;
|
||||
while (!updateNotifySettingPeers.isEmpty()) {
|
||||
@@ -2750,6 +2764,8 @@ void MainWidget::start(const MTPUser &user) {
|
||||
Local::writeMtpData();
|
||||
}
|
||||
|
||||
Local::readSavedPeers();
|
||||
|
||||
cSetOtherOnline(0);
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, user));
|
||||
App::app()->startUpdateCheck();
|
||||
@@ -3024,8 +3040,7 @@ void MainWidget::gotNotifySetting(MTPInputNotifyPeer peer, const MTPPeerNotifySe
|
||||
switch (peer.c_inputNotifyPeer().vpeer.type()) {
|
||||
case mtpc_inputPeerEmpty: applyNotifySetting(MTP_notifyPeer(MTP_peerUser(MTP_int(0))), settings); break;
|
||||
case mtpc_inputPeerSelf: applyNotifySetting(MTP_notifyPeer(MTP_peerUser(MTP_int(MTP::authedId()))), settings); break;
|
||||
case mtpc_inputPeerContact: applyNotifySetting(MTP_notifyPeer(MTP_peerUser(peer.c_inputNotifyPeer().vpeer.c_inputPeerContact().vuser_id)), settings); break;
|
||||
case mtpc_inputPeerForeign: applyNotifySetting(MTP_notifyPeer(MTP_peerUser(peer.c_inputNotifyPeer().vpeer.c_inputPeerForeign().vuser_id)), settings); break;
|
||||
case mtpc_inputPeerUser: applyNotifySetting(MTP_notifyPeer(MTP_peerUser(peer.c_inputNotifyPeer().vpeer.c_inputPeerUser().vuser_id)), settings); break;
|
||||
case mtpc_inputPeerChat: applyNotifySetting(MTP_notifyPeer(MTP_peerChat(peer.c_inputNotifyPeer().vpeer.c_inputPeerChat().vchat_id)), settings); break;
|
||||
}
|
||||
break;
|
||||
@@ -3334,7 +3349,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
return;
|
||||
}
|
||||
bool out = (d.vflags.v & MTPDmessage_flag_out);
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, MTPnullEntities));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
@@ -3354,7 +3369,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||
return;
|
||||
}
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, MTPnullEntities));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
@@ -3483,11 +3498,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
History *history = App::historyLoaded(App::peerFromUser(d.vuser_id));
|
||||
UserData *user = App::userLoaded(d.vuser_id.v);
|
||||
if (history && user) {
|
||||
if (d.vaction.type() == mtpc_sendMessageTypingAction) {
|
||||
App::histories().regTyping(history, user);
|
||||
} else if (d.vaction.type() == mtpc_sendMessageCancelAction) {
|
||||
history->unregTyping(user);
|
||||
}
|
||||
App::histories().regSendAction(history, user, d.vaction);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -3496,7 +3507,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
History *history = App::historyLoaded(App::peerFromChat(d.vchat_id));
|
||||
UserData *user = (d.vuser_id.v == MTP::authedId()) ? 0 : App::userLoaded(d.vuser_id.v);
|
||||
if (history && user) {
|
||||
App::histories().regTyping(history, user);
|
||||
App::histories().regSendAction(history, user, d.vaction);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -3638,6 +3649,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateUserBlocked: {
|
||||
const MTPDupdateUserBlocked &d(update.c_updateUserBlocked());
|
||||
if (UserData *user = App::userLoaded(d.vuser_id.v)) {
|
||||
user->blocked = d.vblocked.v ? UserIsBlocked : UserIsNotBlocked;
|
||||
App::markPeerUpdated(user);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateNewAuthorization: {
|
||||
|
||||
@@ -281,11 +281,11 @@ public:
|
||||
DragState getDragState(const QMimeData *mime);
|
||||
|
||||
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
||||
void deleteHistory(PeerData *peer, const MTPUpdates &updates);
|
||||
void deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates);
|
||||
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
||||
void deleteMessages(const QVector<MTPint> &ids);
|
||||
void deletedContact(UserData *user, const MTPcontacts_Link &result);
|
||||
void deleteHistoryAndContact(UserData *user, const MTPcontacts_Link &result);
|
||||
void deleteConversation(PeerData *peer);
|
||||
void clearHistory(PeerData *peer);
|
||||
void removeContact(UserData *user);
|
||||
|
||||
@@ -421,6 +421,8 @@ public slots:
|
||||
void onTopBarClick();
|
||||
void onPeerShown(PeerData *peer);
|
||||
|
||||
void searchInPeer(PeerData *peer);
|
||||
|
||||
void onUpdateNotifySettings();
|
||||
|
||||
void onPhotosSelect();
|
||||
|
||||
@@ -775,18 +775,14 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
|
||||
_x = (width() - _w) / 2;
|
||||
_y = (height() - _h) / 2;
|
||||
_width = _w;
|
||||
if (_photo->user == WebPageUserId && _msgid) {
|
||||
if (HistoryItem *item = App::histItemById(_msgid)) {
|
||||
if (dynamic_cast<HistoryForwarded*>(item)) {
|
||||
_from = static_cast<HistoryForwarded*>(item)->fromForwarded();
|
||||
} else {
|
||||
_from = item->from();
|
||||
}
|
||||
if (_msgid && item) {
|
||||
if (HistoryForwarded *fwd = item->toHistoryForwarded()) {
|
||||
_from = fwd->fromForwarded();
|
||||
} else {
|
||||
_from = App::user(_photo->user);
|
||||
_from = item->from();
|
||||
}
|
||||
} else {
|
||||
_from = App::user(_photo->user);
|
||||
_from = _user;
|
||||
}
|
||||
updateControls();
|
||||
_photo->full->load();
|
||||
@@ -955,10 +951,10 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
|
||||
}
|
||||
_x = (width() - _w) / 2;
|
||||
_y = (height() - _h) / 2;
|
||||
if (HistoryForwarded *fwd = dynamic_cast<HistoryForwarded*>(item)) {
|
||||
_from = fwd->fromForwarded()->asUser();
|
||||
if (HistoryForwarded *fwd = item->toHistoryForwarded()) {
|
||||
_from = fwd->fromForwarded();
|
||||
} else {
|
||||
_from = item->from()->asUser();
|
||||
_from = item->from();
|
||||
}
|
||||
_full = 1;
|
||||
updateControls();
|
||||
@@ -1850,7 +1846,7 @@ void MediaView::loadBack() {
|
||||
if (App::main()) App::main()->loadMediaBack(_history->peer, _overview);
|
||||
} else if (_user && _user->photosCount != 0) {
|
||||
int32 limit = (_index < MediaOverviewStartPerPage && _user->photos.size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage;
|
||||
_loadRequest = MTP::send(MTPphotos_GetUserPhotos(_user->inputUser, MTP_int(_user->photos.size()), MTP_int(0), MTP_int(limit)), rpcDone(&MediaView::userPhotosLoaded, _user));
|
||||
_loadRequest = MTP::send(MTPphotos_GetUserPhotos(_user->inputUser, MTP_int(_user->photos.size()), MTP_long(0), MTP_int(limit)), rpcDone(&MediaView::userPhotosLoaded, _user));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +150,13 @@ with open('scheme.tl') as f:
|
||||
print('Bad param found: "' + param + '" in line: ' + line);
|
||||
continue;
|
||||
ptype = pmasktype.group(3);
|
||||
if (ptype.find('<') >= 0):
|
||||
templ = re.match(r'^([vV]ector<)([A-Za-z0-9\._]+)>$', ptype);
|
||||
if (templ):
|
||||
ptype = templ.group(1) + 'MTP' + templ.group(2).replace('.', '_') + '>';
|
||||
else:
|
||||
print('Bad template type: ' + ptype);
|
||||
continue;
|
||||
if (not pname in conditions):
|
||||
conditionsList.append(pname);
|
||||
conditions[pname] = pmasktype.group(2);
|
||||
|
||||
@@ -1253,6 +1253,7 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
|
||||
, _pingMsgId(0)
|
||||
, restarted(false)
|
||||
, keyId(0)
|
||||
// , sessionDataMutex(QReadWriteLock::Recursive)
|
||||
, sessionData(data)
|
||||
, myKeyLock(false)
|
||||
, authKeyData(0)
|
||||
@@ -1856,7 +1857,7 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||
}
|
||||
}
|
||||
mtpRequestData::padding(toSendRequest);
|
||||
sendRequest(toSendRequest, needAnyResponse);
|
||||
sendRequest(toSendRequest, needAnyResponse, lockFinished);
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::retryByTimer() {
|
||||
@@ -1971,8 +1972,11 @@ void MTProtoConnectionPrivate::restart(bool maybeBadKey) {
|
||||
}
|
||||
}
|
||||
|
||||
lockFinished.unlock();
|
||||
doDisconnect();
|
||||
if (_needSessionReset) {
|
||||
|
||||
lockFinished.relock();
|
||||
if (sessionData && _needSessionReset) {
|
||||
resetSession();
|
||||
}
|
||||
restarted = true;
|
||||
@@ -2089,7 +2093,12 @@ void MTProtoConnectionPrivate::onWaitIPv4Failed() {
|
||||
void MTProtoConnectionPrivate::doDisconnect() {
|
||||
destroyConn();
|
||||
|
||||
unlockKey();
|
||||
{
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (sessionData) {
|
||||
unlockKey();
|
||||
}
|
||||
}
|
||||
|
||||
clearAuthKeyData();
|
||||
|
||||
@@ -2113,12 +2122,16 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
DEBUG_LOG(("MTP Error: auth_key for dc %1 busy, cant lock").arg(dc));
|
||||
clearMessages();
|
||||
keyId = 0;
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
mtpAuthKeyPtr key(sessionData->getKey());
|
||||
if (!key || key->keyId() != keyId) {
|
||||
DEBUG_LOG(("MTP Error: auth_key id for dc %1 changed").arg(dc));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -2129,11 +2142,15 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
if (len < 18) { // 2 auth_key_id, 4 msg_key, 2 salt, 2 session, 2 msg_id, 1 seq_no, 1 length, (1 data + 3 padding) min
|
||||
LOG(("TCP Error: bad message received, len %1").arg(len * sizeof(mtpPrime)));
|
||||
TCP_LOG(("TCP Error: bad message %1").arg(mb(encrypted, len * sizeof(mtpPrime)).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
if (keyId != *(uint64*)encrypted) {
|
||||
LOG(("TCP Error: bad auth_key_id %1 instead of %2 received").arg(keyId).arg(*(uint64*)encrypted));
|
||||
TCP_LOG(("TCP Error: bad message %1").arg(mb(encrypted, len * sizeof(mtpPrime)).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -2152,6 +2169,8 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
LOG(("TCP Error: bad msg_len received %1, data size: %2").arg(msgLen).arg(dataBuffer.size()));
|
||||
TCP_LOG(("TCP Error: bad message %1").arg(mb(encrypted, len * sizeof(mtpPrime)).str()));
|
||||
_conn->received().pop_front();
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
uchar sha1Buffer[20];
|
||||
@@ -2159,6 +2178,8 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
LOG(("TCP Error: bad SHA1 hash after aesDecrypt in message"));
|
||||
TCP_LOG(("TCP Error: bad message %1").arg(mb(encrypted, len * sizeof(mtpPrime)).str()));
|
||||
_conn->received().pop_front();
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
TCP_LOG(("TCP Info: decrypted message %1,%2,%3 is %4 len").arg(msgId).arg(seqNo).arg(logBool(needAck)).arg(msgLen + 8 * sizeof(mtpPrime)));
|
||||
@@ -2168,6 +2189,8 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
LOG(("MTP Error: bad server session received"));
|
||||
TCP_LOG(("MTP Error: bad server session %1 instead of %2 in message received").arg(session).arg(serverSession));
|
||||
_conn->received().pop_front();
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -2177,6 +2200,8 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
bool isReply = ((msgId & 0x03) == 1);
|
||||
if (!isReply && ((msgId & 0x03) != 3)) {
|
||||
LOG(("MTP Error: bad msg_id %1 in message received").arg(msgId));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -2252,6 +2277,8 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
|
||||
if (res < 0) {
|
||||
_needSessionReset = (res < -1);
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
retryTimeout = 1; // reset restart() timer
|
||||
@@ -3022,6 +3049,8 @@ void MTProtoConnectionPrivate::onConnected4() {
|
||||
disconnect(_conn4, SIGNAL(connected()), this, SLOT(onConnected4()));
|
||||
if (!_conn4->isConnected()) {
|
||||
LOG(("Connection Error: not connected in onConnected4(), state: %1").arg(_conn4->debugState()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -3030,6 +3059,7 @@ void MTProtoConnectionPrivate::onConnected4() {
|
||||
|
||||
DEBUG_LOG(("MTP Info: connection through IPv4 succeed."));
|
||||
|
||||
lockFinished.unlock();
|
||||
updateAuthKey();
|
||||
}
|
||||
|
||||
@@ -3043,6 +3073,8 @@ void MTProtoConnectionPrivate::onConnected6() {
|
||||
disconnect(_conn6, SIGNAL(connected()), this, SLOT(onConnected6()));
|
||||
if (!_conn6->isConnected()) {
|
||||
LOG(("Connection Error: not connected in onConnected(), state: %1").arg(_conn6->debugState()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -3121,6 +3153,7 @@ void MTProtoConnectionPrivate::updateAuthKey() {
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(pqAnswered()));
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_pq.."));
|
||||
lockFinished.unlock();
|
||||
sendRequestNotSecure(req_pq);
|
||||
}
|
||||
|
||||
@@ -3424,6 +3457,7 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
|
||||
MTPSet_client_DH_params::ResponseType res_client_DH_params;
|
||||
if (!readResponseNotSecure(res_client_DH_params)) {
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -3433,11 +3467,15 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
if (resDH.vnonce != authKeyData->nonce) {
|
||||
LOG(("AuthKey Error: received nonce <> sent nonce (in dh_gen_ok)!"));
|
||||
DEBUG_LOG(("AuthKey Error: received nonce: %1, sent nonce: %2").arg(mb(&resDH.vnonce, 16).str()).arg(mb(&authKeyData->nonce, 16).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
if (resDH.vserver_nonce != authKeyData->server_nonce) {
|
||||
LOG(("AuthKey Error: received server_nonce <> sent server_nonce (in dh_gen_ok)!"));
|
||||
DEBUG_LOG(("AuthKey Error: received server_nonce: %1, sent server_nonce: %2").arg(mb(&resDH.vserver_nonce, 16).str()).arg(mb(&authKeyData->server_nonce, 16).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
authKeyData->new_nonce_buf[32] = 1;
|
||||
@@ -3445,6 +3483,8 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
if (resDH.vnew_nonce_hash1 != *(MTPint128*)(hashSha1(authKeyData->new_nonce_buf, 41, sha1Buffer) + 1)) {
|
||||
LOG(("AuthKey Error: received new_nonce_hash1 did not match!"));
|
||||
DEBUG_LOG(("AuthKey Error: received new_nonce_hash1: %1, new_nonce_buf: %2").arg(mb(&resDH.vnew_nonce_hash1, 16).str()).arg(mb(authKeyData->new_nonce_buf, 41).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -3467,11 +3507,15 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
if (resDH.vnonce != authKeyData->nonce) {
|
||||
LOG(("AuthKey Error: received nonce <> sent nonce (in dh_gen_retry)!"));
|
||||
DEBUG_LOG(("AuthKey Error: received nonce: %1, sent nonce: %2").arg(mb(&resDH.vnonce, 16).str()).arg(mb(&authKeyData->nonce, 16).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
if (resDH.vserver_nonce != authKeyData->server_nonce) {
|
||||
LOG(("AuthKey Error: received server_nonce <> sent server_nonce (in dh_gen_retry)!"));
|
||||
DEBUG_LOG(("AuthKey Error: received server_nonce: %1, sent server_nonce: %2").arg(mb(&resDH.vserver_nonce, 16).str()).arg(mb(&authKeyData->server_nonce, 16).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
authKeyData->new_nonce_buf[32] = 2;
|
||||
@@ -3479,6 +3523,8 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
if (resDH.vnew_nonce_hash2 != *(MTPint128*)(hashSha1(authKeyData->new_nonce_buf, 41, sha1Buffer) + 1)) {
|
||||
LOG(("AuthKey Error: received new_nonce_hash2 did not match!"));
|
||||
DEBUG_LOG(("AuthKey Error: received new_nonce_hash2: %1, new_nonce_buf: %2").arg(mb(&resDH.vnew_nonce_hash2, 16).str()).arg(mb(authKeyData->new_nonce_buf, 41).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
authKeyData->retry_id = authKeyData->auth_key_aux_hash;
|
||||
@@ -3489,11 +3535,15 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
if (resDH.vnonce != authKeyData->nonce) {
|
||||
LOG(("AuthKey Error: received nonce <> sent nonce (in dh_gen_fail)!"));
|
||||
DEBUG_LOG(("AuthKey Error: received nonce: %1, sent nonce: %2").arg(mb(&resDH.vnonce, 16).str()).arg(mb(&authKeyData->nonce, 16).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
if (resDH.vserver_nonce != authKeyData->server_nonce) {
|
||||
LOG(("AuthKey Error: received server_nonce <> sent server_nonce (in dh_gen_fail)!"));
|
||||
DEBUG_LOG(("AuthKey Error: received server_nonce: %1, sent server_nonce: %2").arg(mb(&resDH.vserver_nonce, 16).str()).arg(mb(&authKeyData->server_nonce, 16).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
authKeyData->new_nonce_buf[32] = 3;
|
||||
@@ -3501,13 +3551,20 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
if (resDH.vnew_nonce_hash3 != *(MTPint128*)(hashSha1(authKeyData->new_nonce_buf, 41, sha1Buffer) + 1)) {
|
||||
LOG(("AuthKey Error: received new_nonce_hash3 did not match!"));
|
||||
DEBUG_LOG(("AuthKey Error: received new_nonce_hash3: %1, new_nonce_buf: %2").arg(mb(&resDH.vnew_nonce_hash3, 16).str()).arg(mb(authKeyData->new_nonce_buf, 41).str()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
LOG(("AuthKey Error: dh_gen_fail received!"));
|
||||
} return restart();
|
||||
}
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
|
||||
}
|
||||
LOG(("AuthKey Error: unknown set_client_DH_params_answer received, typeId = %1").arg(res_client_DH_params.type()));
|
||||
|
||||
lockFinished.unlock();
|
||||
return restart();
|
||||
}
|
||||
|
||||
@@ -3646,7 +3703,7 @@ bool MTProtoConnectionPrivate::readResponseNotSecure(TResponse &response) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MTProtoConnectionPrivate::sendRequest(mtpRequest &request, bool needAnyResponse) {
|
||||
bool MTProtoConnectionPrivate::sendRequest(mtpRequest &request, bool needAnyResponse, QReadLocker &lockFinished) {
|
||||
uint32 fullSize = request->size();
|
||||
if (fullSize < 9) return false;
|
||||
|
||||
@@ -3656,6 +3713,8 @@ bool MTProtoConnectionPrivate::sendRequest(mtpRequest &request, bool needAnyResp
|
||||
ReadLockerAttempt lock(sessionData->keyMutex());
|
||||
if (!lock) {
|
||||
DEBUG_LOG(("MTP Info: could not lock key for read in sendBuffer(), dc %1, restarting..").arg(dc));
|
||||
|
||||
lockFinished.unlock();
|
||||
restart();
|
||||
return false;
|
||||
}
|
||||
@@ -3663,6 +3722,8 @@ bool MTProtoConnectionPrivate::sendRequest(mtpRequest &request, bool needAnyResp
|
||||
mtpAuthKeyPtr key(sessionData->getKey());
|
||||
if (!key || key->keyId() != keyId) {
|
||||
DEBUG_LOG(("MTP Error: auth_key id for dc %1 changed").arg(dc));
|
||||
|
||||
lockFinished.unlock();
|
||||
restart();
|
||||
return false;
|
||||
}
|
||||
@@ -3729,9 +3790,6 @@ void MTProtoConnectionPrivate::lockKey() {
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::unlockKey() {
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (!sessionData) return;
|
||||
|
||||
if (myKeyLock) {
|
||||
myKeyLock = false;
|
||||
sessionData->keyMutex()->unlock();
|
||||
|
||||
@@ -52,6 +52,7 @@ enum {
|
||||
};
|
||||
|
||||
static const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_int(0), MTP_vector<MTPKeyboardButtonRow>(0));
|
||||
static const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0);
|
||||
|
||||
#include "mtproto/mtpPublicRSA.h"
|
||||
#include "mtproto/mtpAuthKey.h"
|
||||
@@ -410,7 +411,6 @@ public slots:
|
||||
void onError4(bool maybeBadKey = false);
|
||||
void onError6(bool maybeBadKey = false);
|
||||
|
||||
void doDisconnect();
|
||||
void doFinish();
|
||||
|
||||
// Auth key creation packet receive slots
|
||||
@@ -430,6 +430,8 @@ public slots:
|
||||
|
||||
private:
|
||||
|
||||
void doDisconnect();
|
||||
|
||||
void createConn(bool createIPv4, bool createIPv6);
|
||||
void destroyConn(MTPabstractConnection **conn = 0); // 0 - destory all
|
||||
|
||||
@@ -437,7 +439,7 @@ private:
|
||||
mtpMsgId prepareToSend(mtpRequest &request, mtpMsgId currentLastId);
|
||||
mtpMsgId replaceMsgId(mtpRequest &request, mtpMsgId newId);
|
||||
|
||||
bool sendRequest(mtpRequest &request, bool needAnyResponse);
|
||||
bool sendRequest(mtpRequest &request, bool needAnyResponse, QReadLocker &lockFinished);
|
||||
mtpRequestId wasSent(mtpMsgId msgId) const;
|
||||
|
||||
int32 handleOneReceived(const mtpPrime *from, const mtpPrime *end, uint64 msgId, int32 serverTime, uint64 serverSalt, bool badTime);
|
||||
|
||||
@@ -366,7 +366,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||
mtpc_invokeWithLayer17,
|
||||
mtpc_invokeWithLayer18,
|
||||
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||
static const mtpPrime mtpCurrentLayer = 32;
|
||||
static const mtpPrime mtpCurrentLayer = 34;
|
||||
|
||||
template <typename bareT>
|
||||
class MTPBoxed : public bareT {
|
||||
|
||||
@@ -487,33 +487,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("{ inputPeerSelf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_inputPeerContact:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ inputPeerContact");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_inputPeerForeign:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ inputPeerForeign");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_inputPeerChat:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@@ -527,6 +500,20 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_inputPeerUser:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ inputPeerUser");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_inputUserEmpty:
|
||||
to.add("{ inputUserEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
@@ -535,24 +522,11 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("{ inputUserSelf }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_inputUserContact:
|
||||
case mtpc_inputUser:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ inputUserContact");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_inputUserForeign:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ inputUserForeign");
|
||||
to.add("{ inputUser");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
@@ -1374,6 +1348,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 8: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 9: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 10: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPDmessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 11: to.add(" entities: "); ++stages.back(); if (flag & MTPDmessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@@ -1662,10 +1637,8 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" geo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" sizes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" sizes: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@@ -1740,9 +1713,9 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" thumb: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 7: to.add(" dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
@@ -2221,10 +2194,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messages_messageEmpty:
|
||||
to.add("{ messages_messageEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_messages_sentMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@@ -2236,8 +2205,9 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" entities: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@@ -2336,6 +2306,10 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("{ inputMessagesFilterAudioDocuments }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_inputMessagesFilterUrl:
|
||||
to.add("{ inputMessagesFilterUrl }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_updateNewMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@@ -2847,6 +2821,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 7: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 8: to.add(" fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 9: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 10: to.add(" entities: "); ++stages.back(); if (flag & MTPDupdateShortMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@@ -2870,6 +2845,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 8: to.add(" fwd_from_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_from_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 9: to.add(" fwd_date: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_fwd_date) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 10: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 11: to.add(" entities: "); ++stages.back(); if (flag & MTPDupdateShortChatMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@@ -3513,12 +3489,11 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 7: to.add(" dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@@ -4389,6 +4364,179 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_help_appChangelogEmpty:
|
||||
to.add("{ help_appChangelogEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_help_appChangelog:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ help_appChangelog");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityUnknown:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityUnknown");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityMention:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityMention");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityHashtag:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityHashtag");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityBotCommand:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityBotCommand");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityUrl:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityUrl");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityEmail:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityEmail");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityBold:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityBold");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityItalic:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityItalic");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityCode:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityCode");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityPre:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityPre");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" language: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageEntityTextUrl:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageEntityTextUrl");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" length: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" url: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_req_pq:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@@ -5442,6 +5590,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 3: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 6: to.add(" entities: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@@ -5786,7 +5935,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
switch (stage) {
|
||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
@@ -6201,6 +6350,22 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_help_getAppChangelog:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ help_getAppChangelog");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" device_model: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" system_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" app_version: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" lang_code: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_rpc_result:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -132,14 +132,10 @@ null#56730bcc = Null;
|
||||
|
||||
inputPeerEmpty#7f3b18ea = InputPeer;
|
||||
inputPeerSelf#7da07ec9 = InputPeer;
|
||||
inputPeerContact#1023dbe8 user_id:int = InputPeer;
|
||||
inputPeerForeign#9b447325 user_id:int access_hash:long = InputPeer;
|
||||
inputPeerChat#179be863 chat_id:int = InputPeer;
|
||||
|
||||
inputUserEmpty#b98886cf = InputUser;
|
||||
inputUserSelf#f7c1b13f = InputUser;
|
||||
inputUserContact#86e94f65 user_id:int = InputUser;
|
||||
inputUserForeign#655e74ff user_id:int access_hash:long = InputUser;
|
||||
|
||||
inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
|
||||
|
||||
@@ -216,7 +212,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#c3060325 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia reply_markup:flags.6?ReplyMarkup = Message;
|
||||
message#f07814c8 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> = Message;
|
||||
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@@ -237,14 +233,14 @@ messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
|
||||
dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
|
||||
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
photo#c3838076 id:long access_hash:long user_id:int date:int geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
|
||||
photo#cded42fe id:long access_hash:long date:int sizes:Vector<PhotoSize> = Photo;
|
||||
|
||||
photoSizeEmpty#e17e23c type:string = PhotoSize;
|
||||
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
|
||||
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
|
||||
|
||||
videoEmpty#c10658a8 id:long = Video;
|
||||
video#ee9f4a4d id:long access_hash:long user_id:int date:int duration:int size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
|
||||
video#f72887d3 id:long access_hash:long date:int duration:int mime_type:string size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
|
||||
|
||||
geoPointEmpty#1117dd5f = GeoPoint;
|
||||
geoPoint#2049d70c long:double lat:double = GeoPoint;
|
||||
@@ -307,9 +303,7 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
|
||||
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
|
||||
messages.messageEmpty#3f4e0648 = messages.Message;
|
||||
|
||||
messages.sentMessage#4c3d47f3 id:int date:int media:MessageMedia pts:int pts_count:int = messages.SentMessage;
|
||||
messages.sentMessage#8a99d8e0 id:int date:int media:MessageMedia entities:Vector<MessageEntity> pts:int pts_count:int = messages.SentMessage;
|
||||
|
||||
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||
|
||||
@@ -325,6 +319,7 @@ inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
|
||||
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
|
||||
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
|
||||
inputMessagesFilterAudioDocuments#5afbf764 = MessagesFilter;
|
||||
inputMessagesFilterUrl#7ef0dd87 = MessagesFilter;
|
||||
|
||||
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
||||
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||
@@ -346,8 +341,8 @@ updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Ve
|
||||
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
|
||||
|
||||
updatesTooLong#e317af7e = Updates;
|
||||
updateShortMessage#ed5c2127 flags:# id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
|
||||
updateShortChatMessage#52238b3c flags:# id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
|
||||
updateShortMessage#3f32d858 flags:# id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
|
||||
updateShortChatMessage#f9409b3d flags:# id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates;
|
||||
updateShort#78d4dec1 update:Update date:int = Updates;
|
||||
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
|
||||
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
|
||||
@@ -454,7 +449,7 @@ inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
|
||||
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
|
||||
|
||||
audioEmpty#586988d8 id:long = Audio;
|
||||
audio#c7ac6496 id:long access_hash:long user_id:int date:int duration:int mime_type:string size:int dc_id:int = Audio;
|
||||
audio#f9e35055 id:long access_hash:long date:int duration:int mime_type:string size:int dc_id:int = Audio;
|
||||
|
||||
documentEmpty#36f8c871 id:long = Document;
|
||||
document#f9a39f4f id:long access_hash:long date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
|
||||
@@ -607,6 +602,25 @@ replyKeyboardHide#a03e5b85 flags:# = ReplyMarkup;
|
||||
replyKeyboardForceReply#f4108aa0 flags:# = ReplyMarkup;
|
||||
replyKeyboardMarkup#3502758c flags:# rows:Vector<KeyboardButtonRow> = ReplyMarkup;
|
||||
|
||||
inputPeerUser#7b8e7de6 user_id:int access_hash:long = InputPeer;
|
||||
|
||||
inputUser#d8292816 user_id:int access_hash:long = InputUser;
|
||||
|
||||
help.appChangelogEmpty#af7e0394 = help.AppChangelog;
|
||||
help.appChangelog#4668e6bd text:string = help.AppChangelog;
|
||||
|
||||
messageEntityUnknown#bb92ba95 offset:int length:int = MessageEntity;
|
||||
messageEntityMention#fa04579d offset:int length:int = MessageEntity;
|
||||
messageEntityHashtag#6f635b0d offset:int length:int = MessageEntity;
|
||||
messageEntityBotCommand#6cef8ac7 offset:int length:int = MessageEntity;
|
||||
messageEntityUrl#6ed02538 offset:int length:int = MessageEntity;
|
||||
messageEntityEmail#64e475c2 offset:int length:int = MessageEntity;
|
||||
messageEntityBold#bd610bc9 offset:int length:int = MessageEntity;
|
||||
messageEntityItalic#826f8b60 offset:int length:int = MessageEntity;
|
||||
messageEntityCode#28a20571 offset:int length:int = MessageEntity;
|
||||
messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
|
||||
messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@@ -658,7 +672,7 @@ messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHis
|
||||
messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||
messages.sendMessage#fc55e6b5 flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup = messages.SentMessage;
|
||||
messages.sendMessage#df12390 flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = messages.SentMessage;
|
||||
messages.sendMedia#c8f16791 flags:# peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
|
||||
messages.forwardMessages#55e1728d peer:InputPeer id:Vector<int> random_id:Vector<long> = Updates;
|
||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||
@@ -685,7 +699,7 @@ help.getAppUpdate#c812ac7e device_model:string system_version:string app_version
|
||||
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
|
||||
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
|
||||
|
||||
photos.getUserPhotos#b7ee553c user_id:InputUser offset:int max_id:int limit:int = photos.Photos;
|
||||
photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
|
||||
|
||||
messages.forwardMessage#33963bf9 peer:InputPeer id:int random_id:long = Updates;
|
||||
messages.sendBroadcast#bf73f4da contacts:Vector<InputUser> random_id:Vector<long> message:string media:InputMedia = Updates;
|
||||
@@ -770,3 +784,5 @@ messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet
|
||||
messages.installStickerSet#7b30c3a6 stickerset:InputStickerSet disabled:Bool = Bool;
|
||||
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
|
||||
messages.startBot#1b3e0ffc bot:InputUser chat_id:int random_id:long start_param:string = Updates;
|
||||
|
||||
help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog;
|
||||
|
||||
@@ -55,7 +55,6 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
|
||||
// settings
|
||||
_enableNotifications(this, lang(lng_profile_enable_notifications)),
|
||||
_clearHistory(this, lang(lng_profile_clear_history)),
|
||||
|
||||
// shared media
|
||||
_allMediaTypes(false),
|
||||
@@ -65,6 +64,14 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
_mediaDocuments(this, QString()),
|
||||
_mediaAudios(this, QString()),
|
||||
|
||||
// actions
|
||||
_searchInPeer(this, lang(lng_profile_search_messages)),
|
||||
_clearHistory(this, lang(lng_profile_clear_history)),
|
||||
_deleteConversation(this, lang(_peer->chat ? lng_profile_clear_and_exit : lng_profile_delete_conversation)),
|
||||
_wasBlocked(_peerUser ? _peerUser->blocked : UserBlockUnknown),
|
||||
_blockRequest(0),
|
||||
_blockUser(this, lang((_peerUser && _peerUser->botInfo) ? lng_profile_block_bot : lng_profile_block_user), st::btnRedLink),
|
||||
|
||||
// participants
|
||||
_pHeight(st::profileListPhotoSize + st::profileListPadding.height() * 2),
|
||||
_kickWidth(st::linkFont->m.width(lang(lng_profile_kick))),
|
||||
@@ -76,12 +83,15 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
|
||||
|
||||
if (_peerUser) {
|
||||
if (_peerUser->blocked == UserIsBlocked) {
|
||||
_blockUser.setText(lang(_peerUser->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user));
|
||||
}
|
||||
_phoneText = App::formatPhone(_peerUser->phone);
|
||||
PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0;
|
||||
if (userPhoto && userPhoto->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(userPhoto, _peer));
|
||||
}
|
||||
if ((_peerUser->botInfo && !_peerUser->botInfo->inited) || (_peerUser->photoId == UnknownPeerPhotoId) || (_peerUser->photoId && !userPhoto->date)) {
|
||||
if ((_peerUser->botInfo && !_peerUser->botInfo->inited) || (_peerUser->photoId == UnknownPeerPhotoId) || (_peerUser->photoId && !userPhoto->date) || (_peerUser->blocked == UserBlockUnknown)) {
|
||||
App::api()->requestFullPeer(_peer);
|
||||
}
|
||||
} else {
|
||||
@@ -96,7 +106,6 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
|
||||
// profile
|
||||
_nameText.setText(st::profileNameFont, _nameCache, _textNameOptions);
|
||||
|
||||
connect(&_uploadPhoto, SIGNAL(clicked()), this, SLOT(onUpdatePhoto()));
|
||||
connect(&_addParticipant, SIGNAL(clicked()), this, SLOT(onAddParticipant()));
|
||||
connect(&_sendMessage, SIGNAL(clicked()), this, SLOT(onSendMessage()));
|
||||
@@ -149,7 +158,6 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
|
||||
// settings
|
||||
connect(&_enableNotifications, SIGNAL(clicked()), this, SLOT(onEnableNotifications()));
|
||||
connect(&_clearHistory, SIGNAL(clicked()), this, SLOT(onClearHistory()));
|
||||
|
||||
// shared media
|
||||
connect(&_mediaShowAll, SIGNAL(clicked()), this, SLOT(onMediaShowAll()));
|
||||
@@ -163,6 +171,12 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
_mediaLinks[OverviewAudios] = &_mediaAudios;
|
||||
App::main()->preloadOverviews(_peer);
|
||||
|
||||
// actions
|
||||
connect(&_searchInPeer, SIGNAL(clicked()), this, SLOT(onSearchInPeer()));
|
||||
connect(&_clearHistory, SIGNAL(clicked()), this, SLOT(onClearHistory()));
|
||||
connect(&_deleteConversation, SIGNAL(clicked()), this, SLOT(onDeleteConversation()));
|
||||
connect(&_blockUser, SIGNAL(clicked()), this, SLOT(onBlockUser()));
|
||||
|
||||
App::contextItem(0);
|
||||
|
||||
resizeEvent(0);
|
||||
@@ -181,6 +195,10 @@ void ProfileInner::onSendMessage() {
|
||||
App::main()->showPeerHistory(_peer->id, ShowAtUnreadMsgId);
|
||||
}
|
||||
|
||||
void ProfileInner::onSearchInPeer() {
|
||||
App::main()->searchInPeer(_peer);
|
||||
}
|
||||
|
||||
void ProfileInner::onEnableNotifications() {
|
||||
App::main()->updateNotifySetting(_peer, _enableNotifications.checked());
|
||||
}
|
||||
@@ -244,17 +262,54 @@ void ProfileInner::onUpdatePhoto() {
|
||||
}
|
||||
|
||||
void ProfileInner::onClearHistory() {
|
||||
ConfirmBox *box = new ConfirmBox(lng_sure_delete_history(lt_contact, _peer->name));
|
||||
ConfirmBox *box = new ConfirmBox(_peer->chat ? lng_sure_delete_group_history(lt_group, _peer->name) : lng_sure_delete_history(lt_contact, _peer->name));
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onClearHistorySure()));
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
||||
void ProfileInner::onClearHistorySure() {
|
||||
App::main()->showDialogs();
|
||||
App::wnd()->hideLayer();
|
||||
App::main()->clearHistory(_peer);
|
||||
}
|
||||
|
||||
void ProfileInner::onDeleteConversation() {
|
||||
ConfirmBox *box = new ConfirmBox(_peer->chat ? lng_sure_delete_and_exit(lt_group, _peer->name) : lng_sure_delete_history(lt_contact, _peer->name));
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onDeleteConversationSure()));
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
||||
void ProfileInner::onDeleteConversationSure() {
|
||||
if (_peer->chat) {
|
||||
App::wnd()->hideLayer();
|
||||
App::main()->showDialogs();
|
||||
MTP::send(MTPmessages_DeleteChatUser(MTP_int(_peer->id & 0xFFFFFFFF), App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _peer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _peer));
|
||||
} else {
|
||||
App::main()->deleteConversation(_peer);
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileInner::onBlockUser() {
|
||||
if (!_peerUser || _blockRequest) return;
|
||||
if (_peerUser->blocked == UserIsBlocked) {
|
||||
_blockRequest = MTP::send(MTPcontacts_Unblock(_peerUser->inputUser), rpcDone(&ProfileInner::blockDone, false), rpcFail(&ProfileInner::blockFail));
|
||||
} else {
|
||||
_blockRequest = MTP::send(MTPcontacts_Block(_peerUser->inputUser), rpcDone(&ProfileInner::blockDone, true), rpcFail(&ProfileInner::blockFail));
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileInner::blockDone(bool blocked, const MTPBool &result) {
|
||||
_blockRequest = 0;
|
||||
if (!_peerUser) return;
|
||||
_peerUser->blocked = blocked ? UserIsBlocked : UserIsNotBlocked;
|
||||
emit App::main()->peerUpdated(_peerUser);
|
||||
}
|
||||
|
||||
bool ProfileInner::blockFail(const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
//_blockRequest = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProfileInner::onAddParticipant() {
|
||||
App::wnd()->showLayer(new ContactsBox(_peerChat));
|
||||
}
|
||||
@@ -384,6 +439,10 @@ void ProfileInner::peerUpdated(PeerData *data) {
|
||||
if (_peerUser) {
|
||||
_phoneText = App::formatPhone(_peerUser->phone);
|
||||
if (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) photo = App::photo(_peerUser->photoId);
|
||||
if (_wasBlocked != _peerUser->blocked) {
|
||||
_wasBlocked = _peerUser->blocked;
|
||||
_blockUser.setText(lang((_peerUser->blocked == UserIsBlocked) ? (_peerUser->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_peerUser->botInfo ? lng_profile_block_bot : lng_profile_block_user)));
|
||||
}
|
||||
} else {
|
||||
if (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) photo = App::photo(_peerChat->photoId);
|
||||
}
|
||||
@@ -610,6 +669,15 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
}
|
||||
|
||||
// actions
|
||||
p.setFont(st::profileHeaderFont->f);
|
||||
p.setPen(st::profileHeaderColor->p);
|
||||
p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(lng_profile_actions_section));
|
||||
top += st::profileHeaderSkip;
|
||||
|
||||
top += _searchInPeer.height() + st::setLittleSkip + _clearHistory.height() + st::setLittleSkip + _deleteConversation.height();
|
||||
if (_peerUser && App::userFromPeer(_peerUser->id) != MTP::authedId()) top += st::setSectionSkip + _blockUser.height();
|
||||
|
||||
// participants
|
||||
if (_peerChat && (_peerChat->count > 0 || !_participants.isEmpty())) {
|
||||
QString sectionHeader = lang(_participants.isEmpty() ? lng_profile_loading : lng_profile_participants_section);
|
||||
@@ -707,7 +775,7 @@ void ProfileInner::updateSelected() {
|
||||
update(QRect(_left, _aboutTop, _width, _aboutHeight));
|
||||
}
|
||||
|
||||
int32 partfrom = _mediaAudios.y() + _mediaAudios.height() + st::profileHeaderSkip;
|
||||
int32 partfrom = _deleteConversation.y() + _deleteConversation.height() + st::profileHeaderSkip;
|
||||
int32 newSelected = (lp.x() >= _left - st::profileListPadding.width() && lp.x() < _left + _width + st::profileListPadding.width() && lp.y() >= partfrom) ? (lp.y() - partfrom) / _pHeight : -1;
|
||||
|
||||
UserData *newKickOver = 0;
|
||||
@@ -874,6 +942,16 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
}
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
|
||||
// actions
|
||||
top += st::profileHeaderSkip;
|
||||
_searchInPeer.move(_left, top); top += _searchInPeer.height() + st::setLittleSkip;
|
||||
_clearHistory.move(_left, top); top += _clearHistory.height() + st::setLittleSkip;
|
||||
_deleteConversation.move(_left, top); top += _deleteConversation.height();
|
||||
if (_peerUser && App::userFromPeer(_peerUser->id) != MTP::authedId()) {
|
||||
top += st::setSectionSkip;
|
||||
_blockUser.move(_left, top); top += _blockUser.height();
|
||||
}
|
||||
|
||||
// participants
|
||||
if (_peerChat && (_peerChat->count > 0 || !_participants.isEmpty())) {
|
||||
top += st::profileHeaderSkip;
|
||||
@@ -883,7 +961,6 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
}
|
||||
}
|
||||
top += st::profileHeaderTop + st::profileHeaderFont->ascent - st::linkFont->ascent;
|
||||
_clearHistory.move(_left, top);
|
||||
}
|
||||
|
||||
void ProfileInner::contextMenuEvent(QContextMenuEvent *e) {
|
||||
@@ -970,6 +1047,9 @@ void ProfileInner::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type)
|
||||
}
|
||||
|
||||
void ProfileInner::showAll() {
|
||||
_searchInPeer.show();
|
||||
_clearHistory.show();
|
||||
_deleteConversation.show();
|
||||
if (_peerChat) {
|
||||
_sendMessage.hide();
|
||||
_shareContact.hide();
|
||||
@@ -1005,8 +1085,7 @@ void ProfileInner::showAll() {
|
||||
_addParticipant.hide();
|
||||
}
|
||||
}
|
||||
_enableNotifications.show();
|
||||
_clearHistory.hide();
|
||||
_blockUser.hide();
|
||||
} else {
|
||||
_uploadPhoto.hide();
|
||||
_cancelPhoto.hide();
|
||||
@@ -1025,9 +1104,14 @@ void ProfileInner::showAll() {
|
||||
_shareContact.show();
|
||||
_inviteToGroup.hide();
|
||||
}
|
||||
_enableNotifications.show();
|
||||
_clearHistory.show();
|
||||
if (App::userFromPeer(_peerUser->id) != MTP::authedId()) {
|
||||
_blockUser.show();
|
||||
} else {
|
||||
_blockUser.hide();
|
||||
}
|
||||
}
|
||||
_enableNotifications.show();
|
||||
updateNotifySettings();
|
||||
|
||||
// shared media
|
||||
@@ -1070,9 +1154,13 @@ void ProfileInner::showAll() {
|
||||
reorderParticipants();
|
||||
int32 h;
|
||||
if (_peerUser) {
|
||||
h = _clearHistory.y() + _clearHistory.height() + st::profileHeaderSkip;
|
||||
if (App::userFromPeer(_peerUser->id) == MTP::authedId()) {
|
||||
h = _deleteConversation.y() + _deleteConversation.height() + st::profileHeaderSkip;
|
||||
} else {
|
||||
h = _blockUser.y() + _blockUser.height() + st::profileHeaderSkip;
|
||||
}
|
||||
} else {
|
||||
h = _mediaAudios.y() + _mediaAudios.height() + st::profileHeaderSkip;
|
||||
h = _deleteConversation.y() + _deleteConversation.height() + st::profileHeaderSkip;
|
||||
if (!_participants.isEmpty()) {
|
||||
h += st::profileHeaderSkip + _participants.size() * _pHeight;
|
||||
} else if (_peerChat->count > 0) {
|
||||
|
||||
@@ -68,10 +68,14 @@ public slots:
|
||||
void onShareContact();
|
||||
void onInviteToGroup();
|
||||
void onSendMessage();
|
||||
void onSearchInPeer();
|
||||
void onEnableNotifications();
|
||||
|
||||
void onClearHistory();
|
||||
void onClearHistorySure();
|
||||
void onDeleteConversation();
|
||||
void onDeleteConversationSure();
|
||||
void onBlockUser();
|
||||
void onAddParticipant();
|
||||
|
||||
void onUpdatePhoto();
|
||||
@@ -142,7 +146,6 @@ private:
|
||||
|
||||
// settings
|
||||
FlatCheckbox _enableNotifications;
|
||||
LinkButton _clearHistory;
|
||||
|
||||
// shared media
|
||||
bool _allMediaTypes;
|
||||
@@ -150,6 +153,12 @@ private:
|
||||
LinkButton *_mediaLinks[OverviewCount];
|
||||
QString overviewLinkText(int32 type, int32 count);
|
||||
|
||||
// actions
|
||||
LinkButton _searchInPeer, _clearHistory, _deleteConversation;
|
||||
UserBlockedStatus _wasBlocked;
|
||||
mtpRequestId _blockRequest;
|
||||
LinkButton _blockUser;
|
||||
|
||||
// participants
|
||||
int32 _pHeight;
|
||||
int32 _kickWidth, _selectedRow, _lastPreload;
|
||||
@@ -171,6 +180,9 @@ private:
|
||||
QString _onlineText;
|
||||
ContextMenu *_menu;
|
||||
|
||||
void blockDone(bool blocked, const MTPBool &result);
|
||||
bool blockFail(const RPCError &error);
|
||||
|
||||
};
|
||||
|
||||
class ProfileWidget : public QWidget, public RPCSender, public Animated {
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace {
|
||||
|
||||
bool frameless = true;
|
||||
bool finished = true;
|
||||
bool noQtTrayIcon = false, noTryUnity = false;
|
||||
bool noQtTrayIcon = false, noTryUnity = false, tryAppIndicator = false;
|
||||
bool useGtkBase = false, useAppIndicator = false, useStatusIcon = false, trayIconChecked = false, useUnityCount = false;
|
||||
|
||||
AppIndicator *_trayIndicator = 0;
|
||||
@@ -356,7 +356,8 @@ namespace {
|
||||
inited = true;
|
||||
|
||||
QString cdesktop = QString(getenv("XDG_CURRENT_DESKTOP")).toLower();
|
||||
noQtTrayIcon = (cdesktop == qstr("pantheon"));// || (cdesktop == qstr("gnome"));
|
||||
noQtTrayIcon = (cdesktop == qstr("pantheon")) || (cdesktop == qstr("gnome"));
|
||||
tryAppIndicator = (cdesktop == qstr("xfce"));
|
||||
noTryUnity = (cdesktop != qstr("unity"));
|
||||
|
||||
if (noQtTrayIcon) cSetSupportTray(false);
|
||||
@@ -401,6 +402,9 @@ namespace {
|
||||
if (!loadFunction(lib_gtk, "g_type_check_instance_cast", ps_g_type_check_instance_cast)) return;
|
||||
if (!loadFunction(lib_gtk, "g_signal_connect_data", ps_g_signal_connect_data)) return;
|
||||
|
||||
if (!loadFunction(lib_gtk, "g_object_ref_sink", ps_g_object_ref_sink)) return;
|
||||
if (!loadFunction(lib_gtk, "g_object_unref", ps_g_object_unref)) return;
|
||||
|
||||
useGtkBase = true;
|
||||
std::cout << "loaded gtk funcs!\n";
|
||||
}
|
||||
@@ -416,7 +420,7 @@ namespace {
|
||||
|
||||
void setupGtk() {
|
||||
QLibrary lib_gtk, lib_indicator;
|
||||
if (!noQtTrayIcon) {
|
||||
if (!noQtTrayIcon && !tryAppIndicator) {
|
||||
if (!noTryUnity) {
|
||||
if (loadLibrary(lib_gtk, "gtk-3", 0)) {
|
||||
setupGtkBase(lib_gtk);
|
||||
@@ -448,6 +452,14 @@ namespace {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tryAppIndicator) {
|
||||
if (useGtkBase && useAppIndicator) {
|
||||
noQtTrayIcon = true;
|
||||
cSetSupportTray(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!useGtkBase && lib_gtk.isLoaded()) {
|
||||
std::cout << "no appindicator, trying to load gtk..\n";
|
||||
setupGtkBase(lib_gtk);
|
||||
@@ -471,8 +483,6 @@ namespace {
|
||||
if (!loadFunction(lib_gtk, "gtk_status_icon_position_menu", ps_gtk_status_icon_position_menu)) return;
|
||||
if (!loadFunction(lib_gtk, "gtk_menu_popup", ps_gtk_menu_popup)) return;
|
||||
if (!loadFunction(lib_gtk, "gtk_get_current_event_time", ps_gtk_get_current_event_time)) return;
|
||||
if (!loadFunction(lib_gtk, "g_object_ref_sink", ps_g_object_ref_sink)) return;
|
||||
if (!loadFunction(lib_gtk, "g_object_unref", ps_g_object_unref)) return;
|
||||
if (!loadFunction(lib_gtk, "g_idle_add", ps_g_idle_add)) return;
|
||||
useStatusIcon = true;
|
||||
std::cout << "status icon api loaded\n";
|
||||
@@ -1239,6 +1249,10 @@ void psRegisterCustomScheme() {
|
||||
}
|
||||
}
|
||||
|
||||
void psNewVersion() {
|
||||
psRegisterCustomScheme();
|
||||
}
|
||||
|
||||
bool _execUpdater(bool update = true) {
|
||||
static const int MaxLen = 65536, MaxArgsCount = 128;
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@ public:
|
||||
|
||||
void psUpdateCounter();
|
||||
|
||||
bool psHasNativeNotifications() {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0;
|
||||
|
||||
~PsMainWindow();
|
||||
@@ -159,7 +163,7 @@ void psShowInFolder(const QString &name);
|
||||
void psStart();
|
||||
void psFinish();
|
||||
|
||||
void psRegisterCustomScheme();
|
||||
void psNewVersion();
|
||||
|
||||
void psUpdateOverlayed(QWidget *widget);
|
||||
inline QString psConvertFileUrl(const QString &url) {
|
||||
|
||||
@@ -564,7 +564,9 @@ void psClearInitLogs() {
|
||||
}
|
||||
|
||||
void psActivateProcess(uint64 pid) {
|
||||
objc_activateProgram();
|
||||
if (!pid) {
|
||||
objc_activateProgram(App::wnd() ? App::wnd()->winId() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
QString psCurrentCountry() {
|
||||
@@ -651,7 +653,7 @@ void psFinish() {
|
||||
objc_finish();
|
||||
}
|
||||
|
||||
void psRegisterCustomScheme() {
|
||||
void psNewVersion() {
|
||||
objc_registerCustomScheme();
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,10 @@ public:
|
||||
|
||||
void psUpdateCounter();
|
||||
|
||||
bool psHasNativeNotifications() {
|
||||
return !(QSysInfo::macVersion() < QSysInfo::MV_10_8);
|
||||
}
|
||||
|
||||
virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0;
|
||||
|
||||
~PsMainWindow();
|
||||
@@ -189,7 +193,7 @@ void psShowInFolder(const QString &name);
|
||||
void psStart();
|
||||
void psFinish();
|
||||
|
||||
void psRegisterCustomScheme();
|
||||
void psNewVersion();
|
||||
|
||||
void psUpdateOverlayed(QWidget *widget);
|
||||
QString psConvertFileUrl(const QString &url);
|
||||
|
||||
@@ -73,7 +73,7 @@ void objc_execTelegram();
|
||||
|
||||
void objc_registerCustomScheme();
|
||||
|
||||
void objc_activateProgram();
|
||||
void objc_activateProgram(WId winId);
|
||||
bool objc_moveFile(const QString &from, const QString &to);
|
||||
void objc_deleteDir(const QString &dir);
|
||||
|
||||
|
||||
@@ -982,8 +982,12 @@ void objc_execTelegram() {
|
||||
_execUpdater(NO);
|
||||
}
|
||||
|
||||
void objc_activateProgram() {
|
||||
void objc_activateProgram(WId winId) {
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
if (winId) {
|
||||
NSWindow *w = [reinterpret_cast<NSView*>(winId) window];
|
||||
[w makeKeyAndOrderFront:NSApp];
|
||||
}
|
||||
}
|
||||
|
||||
bool objc_moveFile(const QString &from, const QString &to) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,9 @@ public:
|
||||
|
||||
void psUpdateCounter();
|
||||
|
||||
bool psHasNativeNotifications();
|
||||
void psCleanNotifyPhotosIn(int32 dt);
|
||||
|
||||
virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0;
|
||||
|
||||
~PsMainWindow();
|
||||
@@ -77,6 +80,8 @@ public slots:
|
||||
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
|
||||
void psShowTrayMenu();
|
||||
|
||||
void psCleanNotifyPhotos();
|
||||
|
||||
protected:
|
||||
|
||||
bool psHasTrayIcon() const {
|
||||
@@ -100,6 +105,8 @@ private:
|
||||
HMENU ps_menu;
|
||||
HICON ps_iconBig, ps_iconSmall, ps_iconOverlay;
|
||||
|
||||
SingleTimer ps_cleanNotifyPhotosTimer;
|
||||
|
||||
void psDestroyIcons();
|
||||
};
|
||||
|
||||
@@ -161,7 +168,7 @@ void psShowInFolder(const QString &name);
|
||||
void psStart();
|
||||
void psFinish();
|
||||
|
||||
void psRegisterCustomScheme();
|
||||
void psNewVersion();
|
||||
|
||||
void psUpdateOverlayed(TWidget *widget);
|
||||
inline QString psConvertFileUrl(const QString &url) {
|
||||
|
||||
@@ -42,6 +42,7 @@ QString gDialogLastPath, gDialogHelperPath; // optimize QFileDialog
|
||||
bool gSoundNotify = true;
|
||||
bool gDesktopNotify = true;
|
||||
DBINotifyView gNotifyView = dbinvShowPreview;
|
||||
bool gWindowsNotifications = true;
|
||||
bool gStartMinimized = false;
|
||||
bool gStartInTray = false;
|
||||
bool gAutoStart = false;
|
||||
@@ -119,11 +120,7 @@ QString gLangFile;
|
||||
bool gRetina = false;
|
||||
float64 gRetinaFactor = 1.;
|
||||
int32 gIntRetinaFactor = 1;
|
||||
#ifdef Q_OS_MAC
|
||||
bool gCustomNotifies = false;
|
||||
#else
|
||||
bool gCustomNotifies = true;
|
||||
#endif
|
||||
uint64 gInstance = 0.;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@@ -159,8 +156,10 @@ int gOtherOnline = 0;
|
||||
|
||||
float64 gSongVolume = 0.9;
|
||||
|
||||
SavedPeers gSavedPeers;
|
||||
SavedPeersByTime gSavedPeersByTime;
|
||||
|
||||
void settingsParseArgs(int argc, char *argv[]) {
|
||||
gCustomNotifies = true;
|
||||
#ifdef Q_OS_MAC
|
||||
if (QSysInfo::macVersion() < QSysInfo::MV_10_8) {
|
||||
gUpdateURL = QUrl(qsl("http://tdesktop.com/mac32/tupdates/current"));
|
||||
|
||||
@@ -101,6 +101,8 @@ DeclareSetting(bool, DesktopNotify);
|
||||
DeclareSetting(DBINotifyView, NotifyView);
|
||||
DeclareSetting(bool, AutoUpdate);
|
||||
|
||||
DeclareSetting(bool, WindowsNotifications);
|
||||
|
||||
struct TWindowPos {
|
||||
TWindowPos() : moncrc(0), maximized(0), x(0), y(0), w(0), h(0) {
|
||||
}
|
||||
@@ -308,4 +310,10 @@ DeclareSetting(int, OtherOnline);
|
||||
|
||||
DeclareSetting(float64, SongVolume);
|
||||
|
||||
struct PeerData;
|
||||
typedef QMap<PeerData*, QDateTime> SavedPeers;
|
||||
typedef QMultiMap<QDateTime, PeerData*> SavedPeersByTime;
|
||||
DeclareRefSetting(SavedPeers, SavedPeers);
|
||||
DeclareRefSetting(SavedPeersByTime, SavedPeersByTime);
|
||||
|
||||
void settingsParseArgs(int argc, char *argv[]);
|
||||
|
||||
@@ -122,6 +122,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
_desktopNotify(this, lang(lng_settings_desktop_notify), cDesktopNotify()),
|
||||
_senderName(this, lang(lng_settings_show_name), cNotifyView() <= dbinvShowName),
|
||||
_messagePreview(this, lang(lng_settings_show_preview), cNotifyView() <= dbinvShowPreview),
|
||||
_windowsNotifications(this, lang(lng_settings_use_windows), cWindowsNotifications()),
|
||||
_soundNotify(this, lang(lng_settings_sound_notify), cSoundNotify()),
|
||||
|
||||
// general
|
||||
@@ -186,7 +187,10 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
_connectionTypeText(lang(lng_connection_type) + ' '),
|
||||
_connectionTypeWidth(st::linkFont->m.width(_connectionTypeText)),
|
||||
_showSessions(this, lang(lng_settings_show_sessions)),
|
||||
_logOut(this, lang(lng_settings_logout), st::btnLogout)
|
||||
_askQuestion(this, lang(lng_settings_ask_question)),
|
||||
_telegramFAQ(this, lang(lng_settings_faq)),
|
||||
_logOut(this, lang(lng_settings_logout), st::btnLogout),
|
||||
_supportGetRequest(0)
|
||||
{
|
||||
if (self()) {
|
||||
_nameText.setText(st::setNameFont, _nameCache, _textNameOptions);
|
||||
@@ -217,6 +221,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
connect(&_desktopNotify, SIGNAL(changed()), this, SLOT(onDesktopNotify()));
|
||||
connect(&_senderName, SIGNAL(changed()), this, SLOT(onSenderName()));
|
||||
connect(&_messagePreview, SIGNAL(changed()), this, SLOT(onMessagePreview()));
|
||||
connect(&_windowsNotifications, SIGNAL(changed()), this, SLOT(onWindowsNotifications()));
|
||||
connect(&_soundNotify, SIGNAL(changed()), this, SLOT(onSoundNotify()));
|
||||
|
||||
// general
|
||||
@@ -288,6 +293,8 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
connect(&_passwordTurnOff, SIGNAL(clicked()), this, SLOT(onPasswordOff()));
|
||||
connect(&_connectionType, SIGNAL(clicked()), this, SLOT(onConnectionType()));
|
||||
connect(&_showSessions, SIGNAL(clicked()), this, SLOT(onShowSessions()));
|
||||
connect(&_askQuestion, SIGNAL(clicked()), this, SLOT(onAskQuestion()));
|
||||
connect(&_telegramFAQ, SIGNAL(clicked()), this, SLOT(onTelegramFAQ()));
|
||||
connect(&_logOut, SIGNAL(clicked()), App::wnd(), SLOT(onLogout()));
|
||||
|
||||
if (App::main()) {
|
||||
@@ -411,6 +418,9 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||
top += _desktopNotify.height() + st::setLittleSkip;
|
||||
top += _senderName.height() + st::setLittleSkip;
|
||||
top += _messagePreview.height() + st::setSectionSkip;
|
||||
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
|
||||
top += _windowsNotifications.height() + st::setSectionSkip;
|
||||
}
|
||||
top += _soundNotify.height();
|
||||
}
|
||||
|
||||
@@ -637,6 +647,9 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||
_desktopNotify.move(_left, top); top += _desktopNotify.height() + st::setLittleSkip;
|
||||
_senderName.move(_left, top); top += _senderName.height() + st::setLittleSkip;
|
||||
_messagePreview.move(_left, top); top += _messagePreview.height() + st::setSectionSkip;
|
||||
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
|
||||
_windowsNotifications.move(_left, top); top += _windowsNotifications.height() + st::setSectionSkip;
|
||||
}
|
||||
_soundNotify.move(_left, top); top += _soundNotify.height();
|
||||
}
|
||||
|
||||
@@ -719,7 +732,12 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||
_connectionType.move(_left + _connectionTypeWidth, top); top += _connectionType.height() + st::setLittleSkip;
|
||||
if (self()) {
|
||||
_showSessions.move(_left, top); top += _showSessions.height() + st::setSectionSkip;
|
||||
_askQuestion.move(_left, top); top += _askQuestion.height() + st::setLittleSkip;
|
||||
_telegramFAQ.move(_left, top); top += _telegramFAQ.height() + st::setSectionSkip;
|
||||
_logOut.move(_left, top);
|
||||
} else {
|
||||
top += st::setSectionSkip - st::setLittleSkip;
|
||||
_telegramFAQ.move(_left, top);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,7 +763,9 @@ void SettingsInner::keyPressEvent(QKeyEvent *e) {
|
||||
App::wnd()->showLayer(box);
|
||||
from = size;
|
||||
break;
|
||||
} else if (qsl("debugmode").startsWith(str) || qsl("testmode").startsWith(str)) {
|
||||
} else if (str == qstr("loadlang")) {
|
||||
chooseCustomLang();
|
||||
} else if (qsl("debugmode").startsWith(str) || qsl("testmode").startsWith(str) || qsl("loadlang").startsWith(str)) {
|
||||
break;
|
||||
}
|
||||
++from;
|
||||
@@ -810,7 +830,7 @@ bool SettingsInner::animStep(float64 ms) {
|
||||
|
||||
void SettingsInner::updateSize(int32 newWidth) {
|
||||
if (_logOut.isHidden()) {
|
||||
resize(newWidth, _connectionType.geometry().bottom() + st::setBottom);
|
||||
resize(newWidth, _telegramFAQ.geometry().bottom() + st::setBottom);
|
||||
} else {
|
||||
resize(newWidth, _logOut.geometry().bottom() + st::setBottom);
|
||||
}
|
||||
@@ -936,11 +956,17 @@ void SettingsInner::showAll() {
|
||||
_desktopNotify.show();
|
||||
_senderName.show();
|
||||
_messagePreview.show();
|
||||
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
|
||||
_windowsNotifications.show();
|
||||
} else {
|
||||
_windowsNotifications.hide();
|
||||
}
|
||||
_soundNotify.show();
|
||||
} else {
|
||||
_desktopNotify.hide();
|
||||
_senderName.hide();
|
||||
_messagePreview.hide();
|
||||
_windowsNotifications.hide();
|
||||
_soundNotify.hide();
|
||||
}
|
||||
|
||||
@@ -1049,6 +1075,7 @@ void SettingsInner::showAll() {
|
||||
_passwordTurnOff.show();
|
||||
}
|
||||
_showSessions.show();
|
||||
_askQuestion.show();
|
||||
_logOut.show();
|
||||
} else {
|
||||
_passcodeEdit.hide();
|
||||
@@ -1057,8 +1084,10 @@ void SettingsInner::showAll() {
|
||||
_passwordEdit.hide();
|
||||
_passwordTurnOff.hide();
|
||||
_showSessions.hide();
|
||||
_askQuestion.hide();
|
||||
_logOut.hide();
|
||||
}
|
||||
_telegramFAQ.show();
|
||||
}
|
||||
|
||||
void SettingsInner::saveError(const QString &str) {
|
||||
@@ -1067,6 +1096,17 @@ void SettingsInner::saveError(const QString &str) {
|
||||
update();
|
||||
}
|
||||
|
||||
void SettingsInner::supportGot(const MTPhelp_Support &support) {
|
||||
if (!App::main()) return;
|
||||
|
||||
if (support.type() == mtpc_help_support) {
|
||||
const MTPDhelp_support &d(support.c_help_support());
|
||||
UserData *u = App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
||||
App::main()->showPeerHistory(u->id, ShowAtUnreadMsgId);
|
||||
App::wnd()->hideSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsInner::onUpdatePhotoCancel() {
|
||||
if (self()) {
|
||||
App::app()->cancelPhotoUpdate(self()->id);
|
||||
@@ -1110,25 +1150,47 @@ void SettingsInner::onShowSessions() {
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
||||
void SettingsInner::onAskQuestion() {
|
||||
if (!App::self()) return;
|
||||
|
||||
ConfirmBox *box = new ConfirmBox(lang(lng_settings_ask_sure), lang(lng_settings_ask_ok), lang(lng_settings_faq_button));
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onAskQuestionSure()));
|
||||
connect(box, SIGNAL(cancelPressed()), this, SLOT(onTelegramFAQ()));
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
||||
void SettingsInner::onAskQuestionSure() {
|
||||
if (_supportGetRequest) return;
|
||||
_supportGetRequest = MTP::send(MTPhelp_GetSupport(), rpcDone(&SettingsInner::supportGot));
|
||||
}
|
||||
|
||||
void SettingsInner::onTelegramFAQ() {
|
||||
QDesktopServices::openUrl(qsl("https://telegram.org/faq#general"));
|
||||
}
|
||||
|
||||
void SettingsInner::chooseCustomLang() {
|
||||
QString file;
|
||||
QByteArray arr;
|
||||
if (filedialogGetOpenFile(file, arr, qsl("Choose language .strings file"), qsl("Language files (*.strings)"))) {
|
||||
_testlang = QFileInfo(file).absoluteFilePath();
|
||||
LangLoaderPlain loader(_testlang, LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_continue));
|
||||
if (loader.errors().isEmpty()) {
|
||||
LangLoaderResult result = loader.found();
|
||||
QString text = result.value(lng_sure_save_language, langOriginal(lng_sure_save_language)),
|
||||
save = result.value(lng_continue, langOriginal(lng_continue)),
|
||||
cancel = result.value(lng_cancel, langOriginal(lng_cancel));
|
||||
ConfirmBox *box = new ConfirmBox(text, save, cancel);
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onSaveTestLang()));
|
||||
App::wnd()->showLayer(box);
|
||||
} else {
|
||||
App::wnd()->showLayer(new ConfirmBox("Custom lang failed :(\n\nError: " + loader.errors(), true, lang(lng_close)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsInner::onChangeLanguage() {
|
||||
if ((_changeLanguage.clickModifiers() & Qt::ShiftModifier) && (_changeLanguage.clickModifiers() & Qt::AltModifier)) {
|
||||
QString file;
|
||||
QByteArray arr;
|
||||
if (filedialogGetOpenFile(file, arr, qsl("Choose language .strings file"), qsl("Language files (*.strings)"))) {
|
||||
_testlang = QFileInfo(file).absoluteFilePath();
|
||||
LangLoaderPlain loader(_testlang, LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_continue));
|
||||
if (loader.errors().isEmpty()) {
|
||||
LangLoaderResult result = loader.found();
|
||||
QString text = result.value(lng_sure_save_language, langOriginal(lng_sure_save_language)),
|
||||
save = result.value(lng_continue, langOriginal(lng_continue)),
|
||||
cancel = result.value(lng_cancel, langOriginal(lng_cancel));
|
||||
ConfirmBox *box = new ConfirmBox(text, save, cancel);
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onSaveTestLang()));
|
||||
App::wnd()->showLayer(box);
|
||||
} else {
|
||||
App::wnd()->showLayer(new ConfirmBox("Custom lang failed :(\n\nError: " + loader.errors(), true, lang(lng_close)));
|
||||
}
|
||||
}
|
||||
chooseCustomLang();
|
||||
} else {
|
||||
App::wnd()->showLayer(new LanguageBox());
|
||||
}
|
||||
@@ -1349,6 +1411,13 @@ void SettingsInner::onSoundNotify() {
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
|
||||
void SettingsInner::onWindowsNotifications() {
|
||||
cSetWindowsNotifications(!cWindowsNotifications());
|
||||
App::wnd()->notifyClearFast();
|
||||
cSetCustomNotifies(!cWindowsNotifications());
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
|
||||
void SettingsInner::onDesktopNotify() {
|
||||
cSetDesktopNotify(_desktopNotify.checked());
|
||||
if (!_desktopNotify.checked()) {
|
||||
|
||||
@@ -78,6 +78,8 @@ public:
|
||||
|
||||
void showAll();
|
||||
|
||||
void chooseCustomLang();
|
||||
|
||||
void updateChatBackground();
|
||||
void needBackgroundUpdate(bool tile);
|
||||
|
||||
@@ -125,6 +127,8 @@ public slots:
|
||||
void onSenderName();
|
||||
void onMessagePreview();
|
||||
|
||||
void onWindowsNotifications();
|
||||
|
||||
void onReplaceEmojis();
|
||||
void onViewEmojis();
|
||||
|
||||
@@ -162,10 +166,16 @@ public slots:
|
||||
|
||||
void onUpdateLocalStorage();
|
||||
|
||||
void onAskQuestion();
|
||||
void onAskQuestionSure();
|
||||
void onTelegramFAQ();
|
||||
|
||||
private:
|
||||
|
||||
void saveError(const QString &str = QString());
|
||||
|
||||
void supportGot(const MTPhelp_Support &support);
|
||||
|
||||
void setScale(DBIScale newScale);
|
||||
|
||||
QString _testlang, _secretText;
|
||||
@@ -192,7 +202,7 @@ private:
|
||||
LinkButton _chooseUsername;
|
||||
|
||||
// notifications
|
||||
FlatCheckbox _desktopNotify, _senderName, _messagePreview, _soundNotify;
|
||||
FlatCheckbox _desktopNotify, _senderName, _messagePreview, _windowsNotifications, _soundNotify;
|
||||
|
||||
// general
|
||||
LinkButton _changeLanguage;
|
||||
@@ -261,9 +271,11 @@ private:
|
||||
LinkButton _connectionType;
|
||||
QString _connectionTypeText;
|
||||
int32 _connectionTypeWidth;
|
||||
LinkButton _showSessions;
|
||||
LinkButton _showSessions, _askQuestion, _telegramFAQ;
|
||||
FlatButton _logOut;
|
||||
|
||||
mtpRequestId _supportGetRequest;
|
||||
|
||||
void gotPassword(const MTPaccount_Password &result);
|
||||
void offPasswordDone(const MTPBool &result);
|
||||
bool offPasswordFail(const RPCError &error);
|
||||
|
||||
@@ -35,5 +35,7 @@ Q_IMPORT_PLUGIN(QWbmpPlugin)
|
||||
Q_IMPORT_PLUGIN(QWebpPlugin)
|
||||
#elif defined Q_OS_LINUX
|
||||
Q_IMPORT_PLUGIN(QComposePlatformInputContextPlugin)
|
||||
Q_IMPORT_PLUGIN(QIbusPlatformInputContextPlugin)
|
||||
Q_IMPORT_PLUGIN(QFcitxPlatformInputContextPlugin)
|
||||
Q_IMPORT_PLUGIN(QWebpPlugin)
|
||||
#endif
|
||||
|
||||
@@ -90,10 +90,10 @@ NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersP
|
||||
PeerData::PeerData(const PeerId &id) : id(id)
|
||||
, loaded(false)
|
||||
, chat(App::isChat(id))
|
||||
, access(0)
|
||||
, colorIndex(peerColorIndex(id))
|
||||
, color(peerColor(colorIndex))
|
||||
, photo(chat ? chatDefPhoto(colorIndex) : userDefPhoto(colorIndex))
|
||||
, photoId(UnknownPeerPhotoId)
|
||||
, nameVersion(0)
|
||||
, notify(UnknownNotifySettings)
|
||||
{
|
||||
@@ -132,14 +132,16 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone,
|
||||
}
|
||||
}
|
||||
|
||||
void UserData::setPhoto(const MTPUserProfilePhoto &p) {
|
||||
void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer as well
|
||||
PhotoId newPhotoId = photoId;
|
||||
ImagePtr newPhoto = photo;
|
||||
StorageImageLocation newPhotoLoc = photoLoc;
|
||||
switch (p.type()) {
|
||||
case mtpc_userProfilePhoto: {
|
||||
const MTPDuserProfilePhoto d(p.c_userProfilePhoto());
|
||||
newPhotoId = d.vphoto_id.v;
|
||||
newPhoto = ImagePtr(160, 160, d.vphoto_small, userDefPhoto(colorIndex));
|
||||
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
||||
newPhoto = newPhotoLoc.isNull() ? userDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
|
||||
//App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p));
|
||||
} break;
|
||||
default: {
|
||||
@@ -151,11 +153,13 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) {
|
||||
} else {
|
||||
newPhoto = userDefPhoto(colorIndex);
|
||||
}
|
||||
newPhotoLoc = StorageImageLocation();
|
||||
} break;
|
||||
}
|
||||
if (newPhotoId != photoId || newPhoto.v() != photo.v()) {
|
||||
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) {
|
||||
photoId = newPhotoId;
|
||||
photo = newPhoto;
|
||||
photoLoc = newPhotoLoc;
|
||||
emit App::main()->peerPhotoChanged(this);
|
||||
}
|
||||
}
|
||||
@@ -226,6 +230,7 @@ void UserData::setBotInfoVersion(int32 version) {
|
||||
botInfo->inited = false;
|
||||
}
|
||||
}
|
||||
|
||||
void UserData::setBotInfo(const MTPBotInfo &info) {
|
||||
switch (info.type()) {
|
||||
case mtpc_botInfoEmpty:
|
||||
@@ -305,23 +310,33 @@ void UserData::madeAction() {
|
||||
}
|
||||
}
|
||||
|
||||
void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) {
|
||||
void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Local::readPeer as well
|
||||
PhotoId newPhotoId = photoId;
|
||||
ImagePtr newPhoto = photo;
|
||||
StorageImageLocation newPhotoLoc = photoLoc;
|
||||
switch (p.type()) {
|
||||
case mtpc_chatPhoto: {
|
||||
const MTPDchatPhoto d(p.c_chatPhoto());
|
||||
photo = ImagePtr(160, 160, d.vphoto_small, chatDefPhoto(colorIndex));
|
||||
photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex));
|
||||
if (phId != UnknownPeerPhotoId) {
|
||||
photoId = phId;
|
||||
newPhotoId = phId;
|
||||
}
|
||||
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
||||
newPhoto = newPhotoLoc.isNull() ? chatDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
|
||||
// photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex));
|
||||
} break;
|
||||
default: {
|
||||
photo = chatDefPhoto(colorIndex);
|
||||
photoFull = ImagePtr();
|
||||
photoId = 0;
|
||||
newPhotoId = 0;
|
||||
newPhotoLoc = StorageImageLocation();
|
||||
newPhoto = chatDefPhoto(colorIndex);
|
||||
// photoFull = ImagePtr();
|
||||
} break;
|
||||
}
|
||||
emit App::main()->peerPhotoChanged(this);
|
||||
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) {
|
||||
photoId = newPhotoId;
|
||||
photo = newPhoto;
|
||||
photoLoc = newPhotoLoc;
|
||||
emit App::main()->peerPhotoChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PhotoLink::onClick(Qt::MouseButton button) const {
|
||||
@@ -389,7 +404,7 @@ QString saveFileName(const QString &title, const QString &filter, const QString
|
||||
|
||||
void VideoOpenLink::onClick(Qt::MouseButton button) const {
|
||||
VideoData *data = video();
|
||||
if ((!data->user && !data->date) || button != Qt::LeftButton) return;
|
||||
if (!data->date || button != Qt::LeftButton) return;
|
||||
|
||||
QString already = data->already(true);
|
||||
if (!already.isEmpty()) {
|
||||
@@ -409,7 +424,7 @@ void VideoOpenLink::onClick(Qt::MouseButton button) const {
|
||||
}
|
||||
|
||||
void VideoSaveLink::doSave(VideoData *data, bool forceSavingAs) {
|
||||
if (!data->user && !data->date) return;
|
||||
if (!data->date) return;
|
||||
|
||||
QString already = data->already(true);
|
||||
if (!already.isEmpty() && !forceSavingAs) {
|
||||
@@ -441,13 +456,13 @@ void VideoSaveLink::onClick(Qt::MouseButton button) const {
|
||||
|
||||
void VideoCancelLink::onClick(Qt::MouseButton button) const {
|
||||
VideoData *data = video();
|
||||
if ((!data->user && !data->date) || button != Qt::LeftButton) return;
|
||||
if (!data->date || button != Qt::LeftButton) return;
|
||||
|
||||
data->cancel();
|
||||
}
|
||||
|
||||
VideoData::VideoData(const VideoId &id, const uint64 &access, int32 user, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) :
|
||||
id(id), access(access), user(user), date(date), duration(duration), w(w), h(h), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), fileType(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
|
||||
VideoData::VideoData(const VideoId &id, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) :
|
||||
id(id), access(access), date(date), duration(duration), w(w), h(h), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), fileType(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
|
||||
location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
||||
}
|
||||
|
||||
@@ -467,7 +482,7 @@ QString VideoData::already(bool check) {
|
||||
|
||||
void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||
AudioData *data = audio();
|
||||
if ((!data->user && !data->date) || button != Qt::LeftButton) return;
|
||||
if (!data->date || button != Qt::LeftButton) return;
|
||||
|
||||
QString already = data->already(true);
|
||||
bool play = App::hoveredLinkItem() && audioPlayer();
|
||||
@@ -501,7 +516,7 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||
}
|
||||
|
||||
void AudioSaveLink::doSave(AudioData *data, bool forceSavingAs) {
|
||||
if (!data->user && !data->date) return;
|
||||
if (!data->date) return;
|
||||
|
||||
QString already = data->already(true);
|
||||
if (!already.isEmpty() && !forceSavingAs) {
|
||||
@@ -534,7 +549,7 @@ void AudioSaveLink::onClick(Qt::MouseButton button) const {
|
||||
|
||||
void AudioCancelLink::onClick(Qt::MouseButton button) const {
|
||||
AudioData *data = audio();
|
||||
if ((!data->user && !data->date) || button != Qt::LeftButton) return;
|
||||
if (!data->date || button != Qt::LeftButton) return;
|
||||
|
||||
data->cancel();
|
||||
}
|
||||
@@ -554,8 +569,8 @@ bool StickerData::setInstalled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 user, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) :
|
||||
id(id), access(access), user(user), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
|
||||
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) :
|
||||
id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
|
||||
location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
||||
}
|
||||
|
||||
|
||||
@@ -59,8 +59,10 @@ style::color peerColor(int32 index);
|
||||
ImagePtr userDefPhoto(int32 index);
|
||||
ImagePtr chatDefPhoto(int32 index);
|
||||
|
||||
struct ChatData;
|
||||
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
|
||||
|
||||
struct UserData;
|
||||
struct ChatData;
|
||||
struct PeerData {
|
||||
PeerData(const PeerId &id);
|
||||
virtual ~PeerData() {
|
||||
@@ -94,13 +96,13 @@ struct PeerData {
|
||||
|
||||
bool loaded;
|
||||
bool chat;
|
||||
uint64 access;
|
||||
MTPinputPeer input;
|
||||
MTPinputUser inputUser;
|
||||
|
||||
int32 colorIndex;
|
||||
style::color color;
|
||||
ImagePtr photo;
|
||||
PhotoId photoId;
|
||||
StorageImageLocation photoLoc;
|
||||
|
||||
int32 nameVersion;
|
||||
|
||||
@@ -165,11 +167,15 @@ struct BotInfo {
|
||||
QString startToken, startGroupToken;
|
||||
};
|
||||
|
||||
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
|
||||
enum UserBlockedStatus {
|
||||
UserBlockUnknown = 0,
|
||||
UserIsBlocked,
|
||||
UserIsNotBlocked,
|
||||
};
|
||||
|
||||
struct PhotoData;
|
||||
struct UserData : public PeerData {
|
||||
UserData(const PeerId &id) : PeerData(id), photoId(UnknownPeerPhotoId), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) {
|
||||
UserData(const PeerId &id) : PeerData(id), access(0), lnk(new PeerLink(this)), onlineTill(0), contact(-1), blocked(UserBlockUnknown), photosCount(-1), botInfo(0) {
|
||||
}
|
||||
void setPhoto(const MTPUserProfilePhoto &photo);
|
||||
void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username);
|
||||
@@ -180,15 +186,19 @@ struct UserData : public PeerData {
|
||||
|
||||
void madeAction(); // pseudo-online
|
||||
|
||||
uint64 access;
|
||||
|
||||
MTPinputUser inputUser;
|
||||
|
||||
QString firstName;
|
||||
QString lastName;
|
||||
QString username;
|
||||
QString phone;
|
||||
Text nameText;
|
||||
PhotoId photoId;
|
||||
TextLinkPtr lnk;
|
||||
int32 onlineTill;
|
||||
int32 contact; // -1 - not contact, cant add (self, empty, deleted, foreign), 0 - not contact, can add (request), 1 - contact
|
||||
UserBlockedStatus blocked;
|
||||
|
||||
typedef QList<PhotoData*> Photos;
|
||||
Photos photos;
|
||||
@@ -198,7 +208,7 @@ struct UserData : public PeerData {
|
||||
};
|
||||
|
||||
struct ChatData : public PeerData {
|
||||
ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0), photoId(UnknownPeerPhotoId) {
|
||||
ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0) {
|
||||
}
|
||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||
int32 count;
|
||||
@@ -216,8 +226,7 @@ struct ChatData : public PeerData {
|
||||
typedef QMap<UserData*, bool> MarkupSenders;
|
||||
MarkupSenders markupSenders;
|
||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
ImagePtr photoFull;
|
||||
PhotoId photoId;
|
||||
// ImagePtr photoFull;
|
||||
QString invitationUrl;
|
||||
// geo
|
||||
};
|
||||
@@ -228,8 +237,8 @@ inline int32 newMessageFlags(PeerData *p) {
|
||||
|
||||
typedef QMap<char, QPixmap> PreparedPhotoThumbs;
|
||||
struct PhotoData {
|
||||
PhotoData(const PhotoId &id, const uint64 &access = 0, int32 user = 0, int32 date = 0, const ImagePtr &thumb = ImagePtr(), const ImagePtr &medium = ImagePtr(), const ImagePtr &full = ImagePtr()) :
|
||||
id(id), access(access), user(user), date(date), thumb(thumb), medium(medium), full(full), chat(0) {
|
||||
PhotoData(const PhotoId &id, const uint64 &access = 0, int32 date = 0, const ImagePtr &thumb = ImagePtr(), const ImagePtr &medium = ImagePtr(), const ImagePtr &full = ImagePtr()) :
|
||||
id(id), access(access), date(date), thumb(thumb), medium(medium), full(full), chat(0) {
|
||||
}
|
||||
void forget() {
|
||||
thumb->forget();
|
||||
@@ -252,7 +261,6 @@ struct PhotoData {
|
||||
}
|
||||
PhotoId id;
|
||||
uint64 access;
|
||||
int32 user;
|
||||
int32 date;
|
||||
ImagePtr thumb, replyPreview;
|
||||
ImagePtr medium;
|
||||
@@ -292,7 +300,7 @@ enum FileStatus {
|
||||
};
|
||||
|
||||
struct VideoData {
|
||||
VideoData(const VideoId &id, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 w = 0, int32 h = 0, const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
VideoData(const VideoId &id, const uint64 &access = 0, int32 date = 0, int32 duration = 0, int32 w = 0, int32 h = 0, const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
|
||||
void forget() {
|
||||
thumb->forget();
|
||||
@@ -328,7 +336,6 @@ struct VideoData {
|
||||
|
||||
VideoId id;
|
||||
uint64 access;
|
||||
int32 user;
|
||||
int32 date;
|
||||
int32 duration;
|
||||
int32 w, h;
|
||||
@@ -388,7 +395,7 @@ public:
|
||||
};
|
||||
|
||||
struct AudioData {
|
||||
AudioData(const AudioId &id, const uint64 &access = 0, int32 user = 0, int32 date = 0, const QString &mime = QString(), int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
AudioData(const AudioId &id, const uint64 &access = 0, int32 date = 0, const QString &mime = QString(), int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
|
||||
void forget() {
|
||||
}
|
||||
@@ -423,7 +430,6 @@ struct AudioData {
|
||||
|
||||
AudioId id;
|
||||
uint64 access;
|
||||
int32 user;
|
||||
int32 date;
|
||||
QString mime;
|
||||
int32 duration;
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
<RCC>
|
||||
<qresource prefix="/gui">
|
||||
<file>art/fonts/OpenSans-Regular.ttf</file>
|
||||
<file>art/fonts/OpenSans-Bold.ttf</file>
|
||||
<file>art/fonts/OpenSans-Semibold.ttf</file>
|
||||
<file>art/newmsg.wav</file>
|
||||
<file>art/bg.jpg</file>
|
||||
<file>art/bg0.png</file>
|
||||
<file>art/sprite.png</file>
|
||||
<file>art/sprite_125x.png</file>
|
||||
<file>art/sprite_150x.png</file>
|
||||
<file>art/sprite_200x.png</file>
|
||||
<file>art/blank.gif</file>
|
||||
<file>art/icon256.png</file>
|
||||
<file>art/iconbig256.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/ava">
|
||||
<file>art/chatcolor1.png</file>
|
||||
<file>art/chatcolor2.png</file>
|
||||
<file>art/chatcolor3.png</file>
|
||||
<file>art/chatcolor4.png</file>
|
||||
<file>art/usercolor1.png</file>
|
||||
<file>art/usercolor2.png</file>
|
||||
<file>art/usercolor3.png</file>
|
||||
<file>art/usercolor4.png</file>
|
||||
<file>art/usercolor5.png</file>
|
||||
<file>art/usercolor6.png</file>
|
||||
<file>art/usercolor7.png</file>
|
||||
<file>art/usercolor8.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qt-project.org">
|
||||
<file>qmime/freedesktop.org.xml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/langs">
|
||||
<file alias="lang_it.strings">langs/lang_it.strings</file>
|
||||
<file alias="lang_es.strings">langs/lang_es.strings</file>
|
||||
<file alias="lang_de.strings">langs/lang_de.strings</file>
|
||||
<file alias="lang_nl.strings">langs/lang_nl.strings</file>
|
||||
<file alias="lang_pt_BR.strings">langs/lang_pt_BR.strings</file>
|
||||
<file alias="lang_ko.strings">langs/lang_ko.strings</file>
|
||||
</qresource>
|
||||
<qresource prefix="/gui">
|
||||
<file>art/fonts/OpenSans-Regular.ttf</file>
|
||||
<file>art/fonts/OpenSans-Bold.ttf</file>
|
||||
<file>art/fonts/OpenSans-Semibold.ttf</file>
|
||||
<file>art/newmsg.wav</file>
|
||||
<file>art/bg.jpg</file>
|
||||
<file>art/bg0.png</file>
|
||||
<file>art/sprite.png</file>
|
||||
<file>art/sprite_125x.png</file>
|
||||
<file>art/sprite_150x.png</file>
|
||||
<file>art/sprite_200x.png</file>
|
||||
<file>art/blank.gif</file>
|
||||
<file>art/icon256.png</file>
|
||||
<file>art/iconbig256.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/ava">
|
||||
<file>art/chatcolor1.png</file>
|
||||
<file>art/chatcolor2.png</file>
|
||||
<file>art/chatcolor3.png</file>
|
||||
<file>art/chatcolor4.png</file>
|
||||
<file>art/usercolor1.png</file>
|
||||
<file>art/usercolor2.png</file>
|
||||
<file>art/usercolor3.png</file>
|
||||
<file>art/usercolor4.png</file>
|
||||
<file>art/usercolor5.png</file>
|
||||
<file>art/usercolor6.png</file>
|
||||
<file>art/usercolor7.png</file>
|
||||
<file>art/usercolor8.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qt-project.org">
|
||||
<file>qmime/freedesktop.org.xml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/langs">
|
||||
<file alias="lang_it.strings">langs/lang_it.strings</file>
|
||||
<file alias="lang_es.strings">langs/lang_es.strings</file>
|
||||
<file alias="lang_de.strings">langs/lang_de.strings</file>
|
||||
<file alias="lang_nl.strings">langs/lang_nl.strings</file>
|
||||
<file alias="lang_pt_BR.strings">langs/lang_pt_BR.strings</file>
|
||||
<file alias="lang_ko.strings">langs/lang_ko.strings</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -232,55 +232,56 @@ QString translitRusEng(const QString &rus);
|
||||
QString rusKeyboardLayoutSwitch(const QString &from);
|
||||
|
||||
enum DataBlockId {
|
||||
dbiKey = 0x00,
|
||||
dbiUser = 0x01,
|
||||
dbiDcOptionOld = 0x02,
|
||||
dbiMaxGroupCount = 0x03,
|
||||
dbiMutePeer = 0x04,
|
||||
dbiSendKey = 0x05,
|
||||
dbiAutoStart = 0x06,
|
||||
dbiStartMinimized = 0x07,
|
||||
dbiSoundNotify = 0x08,
|
||||
dbiWorkMode = 0x09,
|
||||
dbiSeenTrayTooltip = 0x0a,
|
||||
dbiDesktopNotify = 0x0b,
|
||||
dbiAutoUpdate = 0x0c,
|
||||
dbiLastUpdateCheck = 0x0d,
|
||||
dbiWindowPosition = 0x0e,
|
||||
dbiConnectionType = 0x0f,
|
||||
dbiKey = 0x00,
|
||||
dbiUser = 0x01,
|
||||
dbiDcOptionOld = 0x02,
|
||||
dbiMaxGroupCount = 0x03,
|
||||
dbiMutePeer = 0x04,
|
||||
dbiSendKey = 0x05,
|
||||
dbiAutoStart = 0x06,
|
||||
dbiStartMinimized = 0x07,
|
||||
dbiSoundNotify = 0x08,
|
||||
dbiWorkMode = 0x09,
|
||||
dbiSeenTrayTooltip = 0x0a,
|
||||
dbiDesktopNotify = 0x0b,
|
||||
dbiAutoUpdate = 0x0c,
|
||||
dbiLastUpdateCheck = 0x0d,
|
||||
dbiWindowPosition = 0x0e,
|
||||
dbiConnectionType = 0x0f,
|
||||
// 0x10 reserved
|
||||
dbiDefaultAttach = 0x11,
|
||||
dbiCatsAndDogs = 0x12,
|
||||
dbiReplaceEmojis = 0x13,
|
||||
dbiAskDownloadPath = 0x14,
|
||||
dbiDownloadPath = 0x15,
|
||||
dbiScale = 0x16,
|
||||
dbiEmojiTab = 0x17,
|
||||
dbiRecentEmojisOld = 0x18,
|
||||
dbiLoggedPhoneNumber = 0x19,
|
||||
dbiMutedPeers = 0x1a,
|
||||
dbiDefaultAttach = 0x11,
|
||||
dbiCatsAndDogs = 0x12,
|
||||
dbiReplaceEmojis = 0x13,
|
||||
dbiAskDownloadPath = 0x14,
|
||||
dbiDownloadPath = 0x15,
|
||||
dbiScale = 0x16,
|
||||
dbiEmojiTab = 0x17,
|
||||
dbiRecentEmojisOld = 0x18,
|
||||
dbiLoggedPhoneNumber = 0x19,
|
||||
dbiMutedPeers = 0x1a,
|
||||
// 0x1b reserved
|
||||
dbiNotifyView = 0x1c,
|
||||
dbiSendToMenu = 0x1d,
|
||||
dbiCompressPastedImage = 0x1e,
|
||||
dbiLang = 0x1f,
|
||||
dbiLangFile = 0x20,
|
||||
dbiTileBackground = 0x21,
|
||||
dbiAutoLock = 0x22,
|
||||
dbiDialogLastPath = 0x23,
|
||||
dbiRecentEmojis = 0x24,
|
||||
dbiEmojiVariants = 0x25,
|
||||
dbiRecentStickers = 0x26,
|
||||
dbiDcOption = 0x27,
|
||||
dbiTryIPv6 = 0x28,
|
||||
dbiSongVolume = 0x29,
|
||||
dbiNotifyView = 0x1c,
|
||||
dbiSendToMenu = 0x1d,
|
||||
dbiCompressPastedImage = 0x1e,
|
||||
dbiLang = 0x1f,
|
||||
dbiLangFile = 0x20,
|
||||
dbiTileBackground = 0x21,
|
||||
dbiAutoLock = 0x22,
|
||||
dbiDialogLastPath = 0x23,
|
||||
dbiRecentEmojis = 0x24,
|
||||
dbiEmojiVariants = 0x25,
|
||||
dbiRecentStickers = 0x26,
|
||||
dbiDcOption = 0x27,
|
||||
dbiTryIPv6 = 0x28,
|
||||
dbiSongVolume = 0x29,
|
||||
dbiWindowsNotifications = 0x30,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
|
||||
// 500-600 reserved
|
||||
|
||||
dbiVersion = 666,
|
||||
dbiVersion = 666,
|
||||
};
|
||||
|
||||
enum DBISendKey {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.8.43</string>
|
||||
<string>0.8.50</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
|
||||
@@ -312,7 +312,10 @@ INCLUDEPATH += "/usr/include/dee-1.0"
|
||||
INCLUDEPATH += "/usr/include/libdbusmenu-glib-0.4"
|
||||
|
||||
LIBS += -lcrypto -lssl -lz -ldl -llzma -lexif -lopenal -lavformat -lavcodec -lswresample -lavutil -lopus
|
||||
LIBS += ./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.a
|
||||
LIBS += ./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libcomposeplatforminputcontextplugin.a \
|
||||
./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libibusplatforminputcontextplugin.a \
|
||||
./../../../Libraries/QtStatic/qtbase/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.a
|
||||
LIBS += /usr/local/lib/libxkbcommon.a
|
||||
|
||||
RESOURCES += \
|
||||
./SourceFiles/telegram.qrc \
|
||||
|
||||
Binary file not shown.
@@ -54,14 +54,17 @@
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\</IntDir>
|
||||
<CustomBuildBeforeTargets>
|
||||
</CustomBuildBeforeTargets>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\</IntDir>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -80,7 +83,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Debug;.\..\..\Libraries\libexif-0.6.20\win32\Debug;.\..\..\Libraries\ffmpeg-2.6.3;.\..\..\Libraries\opus\win32\VS2010\Win32\Debug;.\..\..\Libraries\openal-soft\build\Debug;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatDebug;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;imageformats\qwebpd.lib;libeay32MTd.lib;ssleay32MTd.lib;Crypt32.lib;zlibstat.lib;LzmaLib.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;OpenAL32.lib;common.lib;libavformat\libavformat.a;libavcodec\libavcodec.a;libavutil\libavutil.a;libswresample\libswresample.a;opus.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;Shlwapi.lib;Gdiplus.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;imageformats\qwebpd.lib;libeay32MTd.lib;ssleay32MTd.lib;Crypt32.lib;zlibstat.lib;LzmaLib.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;OpenAL32.lib;common.lib;libavformat\libavformat.a;libavcodec\libavcodec.a;libavutil\libavutil.a;libswresample\libswresample.a;opus.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ImageHasSafeExceptionHandlers />
|
||||
<IgnoreSpecificDefaultLibraries>LIBCMT</IgnoreSpecificDefaultLibraries>
|
||||
@@ -108,7 +111,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;.\..\..\Libraries\libexif-0.6.20\win32\Release;.\..\..\Libraries\ffmpeg-2.6.3;.\..\..\Libraries\opus\win32\VS2010\Win32\Release;.\..\..\Libraries\openal-soft\build\Release;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;imageformats\qwebp.lib;libeay32MT.lib;ssleay32MT.lib;Crypt32.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;libavformat\libavformat.a;libavcodec\libavcodec.a;libavutil\libavutil.a;libswresample\libswresample.a;opus.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;Shlwapi.lib;Gdiplus.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;imageformats\qwebp.lib;libeay32MT.lib;ssleay32MT.lib;Crypt32.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;libavformat\libavformat.a;libavcodec\libavcodec.a;libavutil\libavutil.a;libswresample\libswresample.a;opus.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ImageHasSafeExceptionHandlers />
|
||||
<ImportLibrary>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\$(TargetName).lib</ImportLibrary>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
@@ -130,12 +133,13 @@
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalOptions>/Zm110 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;.\..\..\Libraries\libexif-0.6.20\win32\Release;.\..\..\Libraries\ffmpeg-2.6.3;.\..\..\Libraries\opus\win32\VS2010\Win32\Release;.\..\..\Libraries\openal-soft\build\Release;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;imageformats\qwebp.lib;libeay32MT.lib;ssleay32MT.lib;Crypt32.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;libavformat\libavformat.a;libavcodec\libavcodec.a;libavutil\libavutil.a;libswresample\libswresample.a;opus.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;Shlwapi.lib;Gdiplus.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;imageformats\qwebp.lib;libeay32MT.lib;ssleay32MT.lib;Crypt32.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;libavformat\libavformat.a;libavcodec\libavcodec.a;libavutil\libavutil.a;libswresample\libswresample.a;opus.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ImageHasSafeExceptionHandlers>
|
||||
</ImageHasSafeExceptionHandlers>
|
||||
<ImportLibrary>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\$(TargetName).lib</ImportLibrary>
|
||||
|
||||
@@ -1707,7 +1707,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.43;
|
||||
CURRENT_PROJECT_VERSION = 0.8.50;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@@ -1725,7 +1725,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 0.8.43;
|
||||
CURRENT_PROJECT_VERSION = 0.8.50;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||
@@ -1751,10 +1751,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.43;
|
||||
CURRENT_PROJECT_VERSION = 0.8.50;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.43;
|
||||
DYLIB_CURRENT_VERSION = 0.8.50;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
@@ -1885,10 +1885,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.43;
|
||||
CURRENT_PROJECT_VERSION = 0.8.50;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.43;
|
||||
DYLIB_CURRENT_VERSION = 0.8.50;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
echo 0.8 8043 0.8.43 0
|
||||
echo 0.8 8050 0.8.50 1
|
||||
# AppVersionStrMajor AppVersion AppVersionStr DevChannel
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
TARGET = composeplatforminputcontextplugin
|
||||
|
||||
PLUGIN_TYPE = platforminputcontexts
|
||||
PLUGIN_EXTENDS = -
|
||||
PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin
|
||||
load(qt_plugin)
|
||||
|
||||
QT += gui-private
|
||||
|
||||
DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"'
|
||||
|
||||
SOURCES += $$PWD/qcomposeplatforminputcontextmain.cpp \
|
||||
$$PWD/qcomposeplatforminputcontext.cpp \
|
||||
$$PWD/generator/qtablegenerator.cpp \
|
||||
|
||||
HEADERS += $$PWD/qcomposeplatforminputcontext.h \
|
||||
$$PWD/generator/qtablegenerator.h \
|
||||
|
||||
# libxkbcommon
|
||||
contains(QT_CONFIG, xkbcommon-qt): {
|
||||
# dont't need x11 dependency for compose key plugin
|
||||
QT_CONFIG -= use-xkbcommon-x11support
|
||||
# include(../../../3rdparty/xkbcommon.pri)
|
||||
} else {
|
||||
LIBS += $$QMAKE_LIBS_XKBCOMMON
|
||||
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
|
||||
}
|
||||
|
||||
OTHER_FILES += $$PWD/compose.json
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"Keys": [ "fcitx" ]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
TARGET = fcitxplatforminputcontextplugin
|
||||
|
||||
PLUGIN_TYPE = platforminputcontexts
|
||||
PLUGIN_EXTENDS = -
|
||||
PLUGIN_CLASS_NAME = QFcitxPlatformInputContextPlugin
|
||||
load(qt_plugin)
|
||||
|
||||
QT += dbus gui-private
|
||||
SOURCES += $$PWD/fcitxqtconnection.cpp \
|
||||
$$PWD/fcitxqtformattedpreedit.cpp \
|
||||
$$PWD/fcitxqtinputcontextproxy.cpp \
|
||||
$$PWD/fcitxqtinputmethoditem.cpp \
|
||||
$$PWD/fcitxqtinputmethodproxy.cpp \
|
||||
$$PWD/fcitxqtkeyboardlayout.cpp \
|
||||
$$PWD/fcitxqtkeyboardproxy.cpp \
|
||||
$$PWD/keyuni.cpp \
|
||||
$$PWD/main.cpp \
|
||||
$$PWD/qfcitxplatforminputcontext.cpp \
|
||||
$$PWD/utils.cpp
|
||||
|
||||
HEADERS += $$PWD/fcitxqtconnection.h \
|
||||
$$PWD/fcitxqtconnection_p.h \
|
||||
$$PWD/fcitxqtdbusaddons_export.h \
|
||||
$$PWD/fcitxqtdbusaddons_version.h \
|
||||
$$PWD/fcitxqtformattedpreedit.h \
|
||||
$$PWD/fcitxqtinputcontextproxy.h \
|
||||
$$PWD/fcitxqtinputmethoditem.h \
|
||||
$$PWD/fcitxqtinputmethodproxy.h \
|
||||
$$PWD/fcitxqtkeyboardlayout.h \
|
||||
$$PWD/fcitxqtkeyboardproxy.h \
|
||||
$$PWD/keydata.h \
|
||||
$$PWD/keyserver_x11.h \
|
||||
$$PWD/keyuni.h \
|
||||
$$PWD/main.h \
|
||||
$$PWD/qfcitxplatforminputcontext.h \
|
||||
$$PWD/utils.h
|
||||
|
||||
OTHER_FILES += $$PWD/fcitx.json
|
||||
@@ -0,0 +1,369 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2012~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "fcitxqtconnection_p.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <QDir>
|
||||
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
// utils function in fcitx-utils and fcitx-config
|
||||
bool _pid_exists(pid_t pid) {
|
||||
if (pid <= 0)
|
||||
return 0;
|
||||
return !(kill(pid, 0) && (errno == ESRCH));
|
||||
}
|
||||
|
||||
|
||||
FcitxQtConnection::FcitxQtConnection(QObject* parent): QObject(parent)
|
||||
,d_ptr(new FcitxQtConnectionPrivate(this))
|
||||
{
|
||||
}
|
||||
|
||||
void FcitxQtConnection::startConnection()
|
||||
{
|
||||
Q_D(FcitxQtConnection);
|
||||
if (!d->m_initialized) {
|
||||
d->initialize();
|
||||
d->createConnection();
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnection::endConnection()
|
||||
{
|
||||
Q_D(FcitxQtConnection);
|
||||
d->cleanUp();
|
||||
d->finalize();
|
||||
d->m_connectedOnce = false;
|
||||
}
|
||||
|
||||
bool FcitxQtConnection::autoReconnect()
|
||||
{
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_autoReconnect;
|
||||
}
|
||||
|
||||
void FcitxQtConnection::setAutoReconnect(bool a)
|
||||
{
|
||||
Q_D(FcitxQtConnection);
|
||||
d->m_autoReconnect = a;
|
||||
}
|
||||
|
||||
QDBusConnection* FcitxQtConnection::connection()
|
||||
{
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_connection;
|
||||
}
|
||||
|
||||
const QString& FcitxQtConnection::serviceName()
|
||||
{
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_serviceName;
|
||||
}
|
||||
|
||||
bool FcitxQtConnection::isConnected()
|
||||
{
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->isConnected();
|
||||
}
|
||||
|
||||
|
||||
|
||||
FcitxQtConnection::~FcitxQtConnection()
|
||||
{
|
||||
}
|
||||
|
||||
FcitxQtConnectionPrivate::FcitxQtConnectionPrivate(FcitxQtConnection* conn) : QObject(conn)
|
||||
,q_ptr(conn)
|
||||
,m_displayNumber(-1)
|
||||
,m_serviceName(QString("%1-%2").arg("org.fcitx.Fcitx").arg(displayNumber()))
|
||||
,m_connection(0)
|
||||
,m_serviceWatcher(new QDBusServiceWatcher(conn))
|
||||
,m_watcher(new QFileSystemWatcher(this))
|
||||
,m_autoReconnect(true)
|
||||
,m_connectedOnce(false)
|
||||
,m_initialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
FcitxQtConnectionPrivate::~FcitxQtConnectionPrivate()
|
||||
{
|
||||
if (m_connection)
|
||||
delete m_connection;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::initialize() {
|
||||
m_serviceWatcher->setConnection(QDBusConnection::sessionBus());
|
||||
m_serviceWatcher->addWatchedService(m_serviceName);
|
||||
|
||||
QFileInfo info(socketFile());
|
||||
QDir dir(info.path());
|
||||
if (!dir.exists()) {
|
||||
QDir rt(QDir::root());
|
||||
rt.mkpath(info.path());
|
||||
}
|
||||
m_watcher->addPath(info.path());
|
||||
if (info.exists()) {
|
||||
m_watcher->addPath(info.filePath());
|
||||
}
|
||||
|
||||
connect(m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(socketFileChanged()));
|
||||
connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(socketFileChanged()));
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::finalize() {
|
||||
m_serviceWatcher->removeWatchedService(m_serviceName);
|
||||
m_watcher->removePaths(m_watcher->files());
|
||||
m_watcher->removePaths(m_watcher->directories());
|
||||
m_watcher->disconnect(SIGNAL(fileChanged(QString)));
|
||||
m_watcher->disconnect(SIGNAL(directoryChanged(QString)));
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::socketFileChanged() {
|
||||
QFileInfo info(socketFile());
|
||||
if (info.exists()) {
|
||||
if (m_watcher->files().indexOf(info.filePath()) == -1)
|
||||
m_watcher->addPath(info.filePath());
|
||||
}
|
||||
|
||||
QString addr = address();
|
||||
if (addr.isNull())
|
||||
return;
|
||||
|
||||
cleanUp();
|
||||
createConnection();
|
||||
}
|
||||
|
||||
QByteArray FcitxQtConnectionPrivate::localMachineId()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
|
||||
return QDBusConnection::localMachineId();
|
||||
#else
|
||||
QFile file1("/var/lib/dbus/machine-id");
|
||||
QFile file2("/etc/machine-id");
|
||||
QFile* fileToRead = NULL;
|
||||
if (file1.open(QIODevice::ReadOnly)) {
|
||||
fileToRead = &file1;
|
||||
}
|
||||
else if (file2.open(QIODevice::ReadOnly)) {
|
||||
fileToRead = &file2;
|
||||
}
|
||||
if (fileToRead) {
|
||||
QByteArray result = fileToRead->readLine(1024);
|
||||
fileToRead->close();
|
||||
result = result.trimmed();
|
||||
if (!result.isEmpty())
|
||||
return result;
|
||||
}
|
||||
return "machine-id";
|
||||
#endif
|
||||
}
|
||||
|
||||
int FcitxQtConnectionPrivate::displayNumber() {
|
||||
if (m_displayNumber < 0) {
|
||||
QByteArray displayNumber("0");
|
||||
QByteArray display(qgetenv("DISPLAY"));
|
||||
int pos = display.indexOf(':');
|
||||
|
||||
if (pos >= 0) {
|
||||
++pos;
|
||||
int pos2 = display.indexOf('.', pos);
|
||||
if (pos2 > 0) {
|
||||
displayNumber = display.mid(pos, pos2 - pos);
|
||||
} else {
|
||||
displayNumber = display.mid(pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool ok;
|
||||
int d = displayNumber.toInt(&ok);
|
||||
if (ok) {
|
||||
m_displayNumber = d;
|
||||
} else {
|
||||
m_displayNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return m_displayNumber;
|
||||
}
|
||||
|
||||
const QString& FcitxQtConnectionPrivate::socketFile()
|
||||
{
|
||||
if (!m_socketFile.isEmpty())
|
||||
return m_socketFile;
|
||||
|
||||
QString filename = QString("%1-%2").arg(QString::fromLatin1(QDBusConnection::localMachineId())).arg(displayNumber());
|
||||
|
||||
QString home = QString::fromLocal8Bit(qgetenv("XDG_CONFIG_HOME"));
|
||||
if (home.isEmpty()) {
|
||||
home = QDir::homePath().append(QLatin1Literal("/.config"));
|
||||
}
|
||||
m_socketFile = QString("%1/fcitx/dbus/%2").arg(home).arg(filename);
|
||||
|
||||
return m_socketFile;
|
||||
}
|
||||
|
||||
QString FcitxQtConnectionPrivate::address()
|
||||
{
|
||||
QString addr;
|
||||
QByteArray addrVar = qgetenv("FCITX_DBUS_ADDRESS");
|
||||
if (!addrVar.isNull())
|
||||
return QString::fromLocal8Bit(addrVar);
|
||||
|
||||
QFile file(socketFile());
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
return QString();
|
||||
|
||||
const int BUFSIZE = 1024;
|
||||
|
||||
char buffer[BUFSIZE];
|
||||
size_t sz = file.read(buffer, BUFSIZE);
|
||||
file.close();
|
||||
if (sz == 0)
|
||||
return QString();
|
||||
char* p = buffer;
|
||||
while(*p)
|
||||
p++;
|
||||
size_t addrlen = p - buffer;
|
||||
if (sz != addrlen + 2 * sizeof(pid_t) + 1)
|
||||
return QString();
|
||||
|
||||
/* skip '\0' */
|
||||
p++;
|
||||
pid_t *ppid = (pid_t*) p;
|
||||
pid_t daemonpid = ppid[0];
|
||||
pid_t fcitxpid = ppid[1];
|
||||
|
||||
if (!_pid_exists(daemonpid)
|
||||
|| !_pid_exists(fcitxpid))
|
||||
return QString();
|
||||
|
||||
addr = QLatin1String(buffer);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::createConnection() {
|
||||
if (m_connectedOnce && !m_autoReconnect) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_serviceWatcher->disconnect(SIGNAL(serviceOwnerChanged(QString,QString,QString)));
|
||||
QString addr = address();
|
||||
if (!addr.isNull()) {
|
||||
QDBusConnection connection(QDBusConnection::connectToBus(addr, "fcitx"));
|
||||
if (connection.isConnected()) {
|
||||
// qDebug() << "create private";
|
||||
m_connection = new QDBusConnection(connection);
|
||||
}
|
||||
else
|
||||
QDBusConnection::disconnectFromBus("fcitx");
|
||||
}
|
||||
|
||||
if (!m_connection) {
|
||||
QDBusConnection* connection = new QDBusConnection(QDBusConnection::sessionBus());
|
||||
connect(m_serviceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(imChanged(QString,QString,QString)));
|
||||
QDBusReply<bool> registered = connection->interface()->isServiceRegistered(m_serviceName);
|
||||
if (!registered.isValid() || !registered.value()) {
|
||||
delete connection;
|
||||
}
|
||||
else {
|
||||
m_connection = connection;
|
||||
}
|
||||
}
|
||||
|
||||
Q_Q(FcitxQtConnection);
|
||||
if (m_connection) {
|
||||
|
||||
m_connection->connect ("org.freedesktop.DBus.Local",
|
||||
"/org/freedesktop/DBus/Local",
|
||||
"org.freedesktop.DBus.Local",
|
||||
"Disconnected",
|
||||
this,
|
||||
SLOT (dbusDisconnected ()));
|
||||
m_connectedOnce = true;
|
||||
emit q->connected();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FcitxQtConnectionPrivate::dbusDisconnected()
|
||||
{
|
||||
cleanUp();
|
||||
|
||||
createConnection();
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::imChanged(const QString& service, const QString& oldowner, const QString& newowner)
|
||||
{
|
||||
if (service == m_serviceName) {
|
||||
/* old die */
|
||||
if (oldowner.length() > 0 || newowner.length() > 0)
|
||||
cleanUp();
|
||||
|
||||
/* new rise */
|
||||
if (newowner.length() > 0) {
|
||||
QTimer::singleShot(100, this, SLOT(newServiceAppear()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::cleanUp()
|
||||
{
|
||||
Q_Q(FcitxQtConnection);
|
||||
bool doemit = false;
|
||||
QDBusConnection::disconnectFromBus("fcitx");
|
||||
if (m_connection) {
|
||||
delete m_connection;
|
||||
m_connection = 0;
|
||||
doemit = true;
|
||||
}
|
||||
|
||||
if (!m_autoReconnect && m_connectedOnce)
|
||||
finalize();
|
||||
|
||||
/* we want m_connection and finalize being called before the signal
|
||||
* thus isConnected will return false in slot
|
||||
* and startConnection can be called in slot
|
||||
*/
|
||||
if (doemit)
|
||||
emit q->disconnected();
|
||||
}
|
||||
|
||||
bool FcitxQtConnectionPrivate::isConnected()
|
||||
{
|
||||
return m_connection && m_connection->isConnected();
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::newServiceAppear() {
|
||||
if (!isConnected()) {
|
||||
cleanUp();
|
||||
|
||||
createConnection();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2012~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FCITXQTCONNECTION_H
|
||||
#define FCITXQTCONNECTION_H
|
||||
|
||||
#include "fcitxqtdbusaddons_export.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class QDBusConnection;
|
||||
|
||||
class FcitxQtConnectionPrivate;
|
||||
|
||||
|
||||
/**
|
||||
* dbus connection to fcitx
|
||||
**/
|
||||
class FCITXQTDBUSADDONS_EXPORT FcitxQtConnection : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool autoReconnect READ autoReconnect WRITE setAutoReconnect)
|
||||
Q_PROPERTY(bool connected READ isConnected)
|
||||
Q_PROPERTY(QDBusConnection* connection READ connection)
|
||||
Q_PROPERTY(QString serviceName READ serviceName)
|
||||
public:
|
||||
/**
|
||||
* create a new connection
|
||||
*
|
||||
* @param parent
|
||||
**/
|
||||
explicit FcitxQtConnection(QObject* parent = 0);
|
||||
|
||||
/**
|
||||
* destroy the connection
|
||||
**/
|
||||
virtual ~FcitxQtConnection();
|
||||
|
||||
/**
|
||||
* the connection will not start to work until you call this function
|
||||
* you may want to connect to the signal before you call this function
|
||||
**/
|
||||
void startConnection();
|
||||
void endConnection();
|
||||
/**
|
||||
* automatically reconnect if fcitx disappeared
|
||||
*
|
||||
* @param a ...
|
||||
* @return void
|
||||
**/
|
||||
void setAutoReconnect(bool a);
|
||||
|
||||
/**
|
||||
* check this connection is doing automatical reconnect or not
|
||||
*
|
||||
* default value is true
|
||||
**/
|
||||
bool autoReconnect();
|
||||
|
||||
/**
|
||||
* return the current dbus connection to fcitx, notice, the object return
|
||||
* by this function might be deteled if fcitx disappear, or might return 0
|
||||
* if fcitx is not running
|
||||
*
|
||||
* @return QDBusConnection*
|
||||
**/
|
||||
QDBusConnection* connection();
|
||||
/**
|
||||
* current fcitx dbus service name, can be used for create DBus proxy
|
||||
*
|
||||
* @return service name
|
||||
**/
|
||||
const QString& serviceName();
|
||||
/**
|
||||
* check its connected or not
|
||||
**/
|
||||
bool isConnected();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* this signal will be emitted upon fcitx appears
|
||||
**/
|
||||
void connected();
|
||||
/**
|
||||
* this signal will be emitted upon fcitx disappears
|
||||
*
|
||||
* it will come with connected in pair
|
||||
**/
|
||||
void disconnected();
|
||||
|
||||
private:
|
||||
FcitxQtConnectionPrivate * const d_ptr;
|
||||
Q_DECLARE_PRIVATE(FcitxQtConnection);
|
||||
};
|
||||
|
||||
#endif // FCITXCONNECTION_H
|
||||
@@ -0,0 +1,68 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2012~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FCITXQTCONNECTION_P_H
|
||||
#define FCITXQTCONNECTION_P_H
|
||||
|
||||
#include "fcitxqtconnection.h"
|
||||
#include <QtCore/QWeakPointer>
|
||||
#include <QtCore/QFileSystemWatcher>
|
||||
|
||||
class QDBusConnection;
|
||||
class QDBusServiceWatcher;
|
||||
|
||||
class FcitxQtConnectionPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FcitxQtConnectionPrivate(FcitxQtConnection* conn);
|
||||
virtual ~FcitxQtConnectionPrivate();
|
||||
FcitxQtConnection * const q_ptr;
|
||||
Q_DECLARE_PUBLIC(FcitxQtConnection);
|
||||
|
||||
private Q_SLOTS:
|
||||
void imChanged(const QString& service, const QString& oldowner, const QString& newowner);
|
||||
void dbusDisconnected();
|
||||
void cleanUp();
|
||||
void newServiceAppear();
|
||||
void socketFileChanged();
|
||||
|
||||
private:
|
||||
bool isConnected();
|
||||
|
||||
static QByteArray localMachineId();
|
||||
const QString& socketFile();
|
||||
void createConnection();
|
||||
QString address();
|
||||
int displayNumber();
|
||||
void initialize();
|
||||
void finalize();
|
||||
|
||||
int m_displayNumber;
|
||||
QString m_serviceName;
|
||||
QDBusConnection* m_connection;
|
||||
QDBusServiceWatcher* m_serviceWatcher;
|
||||
QFileSystemWatcher* m_watcher;
|
||||
QString m_socketFile;
|
||||
bool m_autoReconnect;
|
||||
bool m_connectedOnce;
|
||||
bool m_initialized;
|
||||
};
|
||||
|
||||
|
||||
#endif // FCITXCONNECTION_P_H
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
#ifndef FCITXQTDBUSADDONS_EXPORT_H
|
||||
#define FCITXQTDBUSADDONS_EXPORT_H
|
||||
|
||||
#ifdef FCITXQTDBUSADDONS_STATIC_DEFINE
|
||||
# define FCITXQTDBUSADDONS_EXPORT
|
||||
# define FCITXQTDBUSADDONS_NO_EXPORT
|
||||
#else
|
||||
# ifndef FCITXQTDBUSADDONS_EXPORT
|
||||
# ifdef FcitxQt5DBusAddons_EXPORTS
|
||||
/* We are building this library */
|
||||
# define FCITXQTDBUSADDONS_EXPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
/* We are using this library */
|
||||
# define FCITXQTDBUSADDONS_EXPORT __attribute__((visibility("default")))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef FCITXQTDBUSADDONS_NO_EXPORT
|
||||
# define FCITXQTDBUSADDONS_NO_EXPORT __attribute__((visibility("hidden")))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FCITXQTDBUSADDONS_DEPRECATED
|
||||
# define FCITXQTDBUSADDONS_DEPRECATED __attribute__ ((__deprecated__))
|
||||
#endif
|
||||
|
||||
#ifndef FCITXQTDBUSADDONS_DEPRECATED_EXPORT
|
||||
# define FCITXQTDBUSADDONS_DEPRECATED_EXPORT FCITXQTDBUSADDONS_EXPORT FCITXQTDBUSADDONS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifndef FCITXQTDBUSADDONS_DEPRECATED_NO_EXPORT
|
||||
# define FCITXQTDBUSADDONS_DEPRECATED_NO_EXPORT FCITXQTDBUSADDONS_NO_EXPORT FCITXQTDBUSADDONS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#define DEFINE_NO_DEPRECATED 0
|
||||
#if DEFINE_NO_DEPRECATED
|
||||
# define FCITXQTDBUSADDONS_NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
#ifndef FCITXQT5DBUSADDONS_VERSION_H
|
||||
#define FCITXQT5DBUSADDONS_VERSION_H
|
||||
|
||||
#define FCITXQT5DBUSADDONS_VERSION_STRING "1.0.0"
|
||||
#define FCITXQT5DBUSADDONS_VERSION_MAJOR 1
|
||||
#define FCITXQT5DBUSADDONS_VERSION_MINOR 0
|
||||
#define FCITXQT5DBUSADDONS_VERSION_PATCH 0
|
||||
#define FCITXQT5DBUSADDONS_VERSION ((1<<16)|(0<<8)|(0))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2012~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QDBusMetaType>
|
||||
|
||||
#include "fcitxqtformattedpreedit.h"
|
||||
|
||||
void FcitxQtFormattedPreedit::registerMetaType()
|
||||
{
|
||||
qRegisterMetaType<FcitxQtFormattedPreedit>("FcitxQtFormattedPreedit");
|
||||
qDBusRegisterMetaType<FcitxQtFormattedPreedit>();
|
||||
qRegisterMetaType<FcitxQtFormattedPreeditList>("FcitxQtFormattedPreeditList");
|
||||
qDBusRegisterMetaType<FcitxQtFormattedPreeditList>();
|
||||
}
|
||||
|
||||
qint32 FcitxQtFormattedPreedit::format() const
|
||||
{
|
||||
return m_format;
|
||||
}
|
||||
|
||||
const QString& FcitxQtFormattedPreedit::string() const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
||||
void FcitxQtFormattedPreedit::setFormat(qint32 format)
|
||||
{
|
||||
m_format = format;
|
||||
}
|
||||
|
||||
void FcitxQtFormattedPreedit::setString(const QString& str)
|
||||
{
|
||||
m_string = str;
|
||||
}
|
||||
|
||||
bool FcitxQtFormattedPreedit::operator==(const FcitxQtFormattedPreedit& preedit) const
|
||||
{
|
||||
return (preedit.m_format == m_format) && (preedit.m_string == m_string);
|
||||
}
|
||||
|
||||
FCITXQTDBUSADDONS_EXPORT
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtFormattedPreedit& preedit)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << preedit.string();
|
||||
argument << preedit.format();
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
FCITXQTDBUSADDONS_EXPORT
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtFormattedPreedit& preedit)
|
||||
{
|
||||
QString str;
|
||||
qint32 format;
|
||||
argument.beginStructure();
|
||||
argument >> str >> format;
|
||||
argument.endStructure();
|
||||
preedit.setString(str);
|
||||
preedit.setFormat(format);
|
||||
return argument;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2012~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FCITX_QT_FORMATTED_PREEDIT_H
|
||||
#define FCITX_QT_FORMATTED_PREEDIT_H
|
||||
|
||||
#include "fcitxqtdbusaddons_export.h"
|
||||
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtDBus/QDBusArgument>
|
||||
|
||||
class FCITXQTDBUSADDONS_EXPORT FcitxQtFormattedPreedit {
|
||||
public:
|
||||
const QString& string() const;
|
||||
qint32 format() const;
|
||||
void setString(const QString& str);
|
||||
void setFormat(qint32 format);
|
||||
|
||||
static void registerMetaType();
|
||||
|
||||
bool operator ==(const FcitxQtFormattedPreedit& preedit) const;
|
||||
private:
|
||||
QString m_string;
|
||||
qint32 m_format;
|
||||
};
|
||||
|
||||
typedef QList<FcitxQtFormattedPreedit> FcitxQtFormattedPreeditList;
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtFormattedPreedit& im);
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtFormattedPreedit& im);
|
||||
|
||||
Q_DECLARE_METATYPE(FcitxQtFormattedPreedit)
|
||||
Q_DECLARE_METATYPE(FcitxQtFormattedPreeditList)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext.xml -i fcitxqtformattedpreedit.h -i fcitxqt_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class FcitxQtInputContextProxy
|
||||
*/
|
||||
|
||||
FcitxQtInputContextProxy::FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
{
|
||||
}
|
||||
|
||||
FcitxQtInputContextProxy::~FcitxQtInputContextProxy()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext.xml -i fcitxqtformattedpreedit.h -i fcitxqt_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef FCITXQTINPUTCONTEXTPROXY_H_1409252990
|
||||
#define FCITXQTINPUTCONTEXTPROXY_H_1409252990
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include "fcitxqtformattedpreedit.h"
|
||||
#include "fcitxqtdbusaddons_export.h"
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.fcitx.Fcitx.InputContext
|
||||
*/
|
||||
class FCITXQTDBUSADDONS_EXPORT FcitxQtInputContextProxy: public QDBusAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.fcitx.Fcitx.InputContext"; }
|
||||
|
||||
public:
|
||||
FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~FcitxQtInputContextProxy();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> CloseIC()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("CloseIC"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> DestroyIC()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("DestroyIC"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> EnableIC()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("EnableIC"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> FocusIn()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("FocusIn"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> FocusOut()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("FocusOut"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> MouseEvent(int x)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x);
|
||||
return asyncCallWithArgumentList(QLatin1String("MouseEvent"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<int> ProcessKeyEvent(uint keyval, uint keycode, uint state, int type, uint time)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state) << QVariant::fromValue(type) << QVariant::fromValue(time);
|
||||
return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> Reset()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCapacity(uint caps)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(caps);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCapacity"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCursorLocation(int x, int y)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCursorLocation"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCursorRect(int x, int y, int w, int h)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(w) << QVariant::fromValue(h);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCursorRect"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingText(const QString &text, uint cursor, uint anchor)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(text) << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetSurroundingText"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingTextPosition(uint cursor, uint anchor)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetSurroundingTextPosition"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void CloseIM();
|
||||
void CommitString(const QString &str);
|
||||
void DeleteSurroundingText(int offset, uint nchar);
|
||||
void EnableIM();
|
||||
void ForwardKey(uint keyval, uint state, int type);
|
||||
void UpdateClientSideUI(const QString &auxup, const QString &auxdown, const QString &preedit, const QString &candidateword, const QString &imname, int cursorpos);
|
||||
void UpdateFormattedPreedit(FcitxQtFormattedPreeditList str, int cursorpos);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2011~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
// Qt
|
||||
#include <QDBusArgument>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
// self
|
||||
#include "fcitxqtinputmethoditem.h"
|
||||
|
||||
bool FcitxQtInputMethodItem::enabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
const QString& FcitxQtInputMethodItem::langCode() const
|
||||
{
|
||||
return m_langCode;
|
||||
}
|
||||
const QString& FcitxQtInputMethodItem::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
const QString& FcitxQtInputMethodItem::uniqueName() const
|
||||
{
|
||||
return m_uniqueName;
|
||||
}
|
||||
void FcitxQtInputMethodItem::setEnabled(bool enable)
|
||||
{
|
||||
m_enabled = enable;
|
||||
}
|
||||
void FcitxQtInputMethodItem::setLangCode(const QString& lang)
|
||||
{
|
||||
m_langCode = lang;
|
||||
}
|
||||
void FcitxQtInputMethodItem::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
void FcitxQtInputMethodItem::setUniqueName(const QString& name)
|
||||
{
|
||||
m_uniqueName = name;
|
||||
}
|
||||
|
||||
void FcitxQtInputMethodItem::registerMetaType()
|
||||
{
|
||||
qRegisterMetaType<FcitxQtInputMethodItem>("FcitxQtInputMethodItem");
|
||||
qDBusRegisterMetaType<FcitxQtInputMethodItem>();
|
||||
qRegisterMetaType<FcitxQtInputMethodItemList>("FcitxQtInputMethodItemList");
|
||||
qDBusRegisterMetaType<FcitxQtInputMethodItemList>();
|
||||
}
|
||||
|
||||
FCITXQTDBUSADDONS_EXPORT
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtInputMethodItem& im)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << im.name();
|
||||
argument << im.uniqueName();
|
||||
argument << im.langCode();
|
||||
argument << im.enabled();
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
FCITXQTDBUSADDONS_EXPORT
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtInputMethodItem& im)
|
||||
{
|
||||
QString name;
|
||||
QString uniqueName;
|
||||
QString langCode;
|
||||
bool enabled;
|
||||
argument.beginStructure();
|
||||
argument >> name >> uniqueName >> langCode >> enabled;
|
||||
argument.endStructure();
|
||||
im.setName(name);
|
||||
im.setUniqueName(uniqueName);
|
||||
im.setLangCode(langCode);
|
||||
im.setEnabled(enabled);
|
||||
return argument;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2011~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FCITX_QT_INPUT_METHOD_ITEM_H
|
||||
#define FCITX_QT_INPUT_METHOD_ITEM_H
|
||||
|
||||
#include "fcitxqtdbusaddons_export.h"
|
||||
|
||||
// Qt
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtDBus/QDBusArgument>
|
||||
|
||||
class FCITXQTDBUSADDONS_EXPORT FcitxQtInputMethodItem
|
||||
{
|
||||
public:
|
||||
const QString& name() const;
|
||||
const QString& uniqueName() const;
|
||||
const QString& langCode() const;
|
||||
bool enabled() const;
|
||||
|
||||
void setName(const QString& name);
|
||||
void setUniqueName(const QString& name);
|
||||
void setLangCode(const QString& name);
|
||||
void setEnabled(bool name);
|
||||
static void registerMetaType();
|
||||
|
||||
inline bool operator < (const FcitxQtInputMethodItem& im) const {
|
||||
if (m_enabled == true && im.m_enabled == false)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_uniqueName;
|
||||
QString m_langCode;
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
typedef QList<FcitxQtInputMethodItem> FcitxQtInputMethodItemList;
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtInputMethodItem& im);
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtInputMethodItem& im);
|
||||
|
||||
Q_DECLARE_METATYPE(FcitxQtInputMethodItem)
|
||||
Q_DECLARE_METATYPE(FcitxQtInputMethodItemList)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputmethodproxy -c FcitxQtInputMethodProxy interfaces/org.fcitx.Fcitx.InputMethod.xml -i fcitxqtinputmethoditem.h -i fcitxqt_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "fcitxqtinputmethodproxy.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class FcitxQtInputMethodProxy
|
||||
*/
|
||||
|
||||
FcitxQtInputMethodProxy::FcitxQtInputMethodProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
{
|
||||
}
|
||||
|
||||
FcitxQtInputMethodProxy::~FcitxQtInputMethodProxy()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputmethodproxy -c FcitxQtInputMethodProxy interfaces/org.fcitx.Fcitx.InputMethod.xml -i fcitxqtinputmethoditem.h -i fcitxqt_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef FCITXQTINPUTMETHODPROXY_H_1409252990
|
||||
#define FCITXQTINPUTMETHODPROXY_H_1409252990
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include "fcitxqtinputmethoditem.h"
|
||||
#include "fcitxqtdbusaddons_export.h"
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.fcitx.Fcitx.InputMethod
|
||||
*/
|
||||
class FCITXQTDBUSADDONS_EXPORT FcitxQtInputMethodProxy: public QDBusAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.fcitx.Fcitx.InputMethod"; }
|
||||
|
||||
public:
|
||||
FcitxQtInputMethodProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~FcitxQtInputMethodProxy();
|
||||
|
||||
Q_PROPERTY(QString CurrentIM READ currentIM WRITE setCurrentIM)
|
||||
inline QString currentIM() const
|
||||
{ return qvariant_cast< QString >(property("CurrentIM")); }
|
||||
inline void setCurrentIM(const QString &value)
|
||||
{ setProperty("CurrentIM", QVariant::fromValue(value)); }
|
||||
|
||||
Q_PROPERTY(FcitxQtInputMethodItemList IMList READ iMList WRITE setIMList)
|
||||
inline FcitxQtInputMethodItemList iMList() const
|
||||
{ return qvariant_cast< FcitxQtInputMethodItemList >(property("IMList")); }
|
||||
inline void setIMList(FcitxQtInputMethodItemList value)
|
||||
{ setProperty("IMList", QVariant::fromValue(value)); }
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> ActivateIM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("ActivateIM"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> Configure()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("Configure"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> ConfigureAddon(const QString &addon)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(addon);
|
||||
return asyncCallWithArgumentList(QLatin1String("ConfigureAddon"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> ConfigureIM(const QString &im)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(im);
|
||||
return asyncCallWithArgumentList(QLatin1String("ConfigureIM"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<int, uint, uint, uint, uint> CreateIC()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("CreateIC"), argumentList);
|
||||
}
|
||||
inline QDBusReply<int> CreateIC(uint &keyval1, uint &state1, uint &keyval2, uint &state2)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("CreateIC"), argumentList);
|
||||
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 5) {
|
||||
keyval1 = qdbus_cast<uint>(reply.arguments().at(1));
|
||||
state1 = qdbus_cast<uint>(reply.arguments().at(2));
|
||||
keyval2 = qdbus_cast<uint>(reply.arguments().at(3));
|
||||
state2 = qdbus_cast<uint>(reply.arguments().at(4));
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<int, bool, uint, uint, uint, uint> CreateICv2(const QString &appname)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appname);
|
||||
return asyncCallWithArgumentList(QLatin1String("CreateICv2"), argumentList);
|
||||
}
|
||||
inline QDBusReply<int> CreateICv2(const QString &appname, bool &enable, uint &keyval1, uint &state1, uint &keyval2, uint &state2)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appname);
|
||||
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("CreateICv2"), argumentList);
|
||||
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 6) {
|
||||
enable = qdbus_cast<bool>(reply.arguments().at(1));
|
||||
keyval1 = qdbus_cast<uint>(reply.arguments().at(2));
|
||||
state1 = qdbus_cast<uint>(reply.arguments().at(3));
|
||||
keyval2 = qdbus_cast<uint>(reply.arguments().at(4));
|
||||
state2 = qdbus_cast<uint>(reply.arguments().at(5));
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<int, bool, uint, uint, uint, uint> CreateICv3(const QString &appname, int pid)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appname) << QVariant::fromValue(pid);
|
||||
return asyncCallWithArgumentList(QLatin1String("CreateICv3"), argumentList);
|
||||
}
|
||||
inline QDBusReply<int> CreateICv3(const QString &appname, int pid, bool &enable, uint &keyval1, uint &state1, uint &keyval2, uint &state2)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appname) << QVariant::fromValue(pid);
|
||||
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("CreateICv3"), argumentList);
|
||||
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 6) {
|
||||
enable = qdbus_cast<bool>(reply.arguments().at(1));
|
||||
keyval1 = qdbus_cast<uint>(reply.arguments().at(2));
|
||||
state1 = qdbus_cast<uint>(reply.arguments().at(3));
|
||||
keyval2 = qdbus_cast<uint>(reply.arguments().at(4));
|
||||
state2 = qdbus_cast<uint>(reply.arguments().at(5));
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> Exit()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("Exit"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<QString> GetCurrentIM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("GetCurrentIM"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<int> GetCurrentState()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("GetCurrentState"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<QString> GetCurrentUI()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("GetCurrentUI"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<QString> GetIMAddon(const QString &im)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(im);
|
||||
return asyncCallWithArgumentList(QLatin1String("GetIMAddon"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> InactivateIM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("InactivateIM"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> ReloadAddonConfig(const QString &addon)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(addon);
|
||||
return asyncCallWithArgumentList(QLatin1String("ReloadAddonConfig"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> ReloadConfig()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("ReloadConfig"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> ResetIMList()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("ResetIMList"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> Restart()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("Restart"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCurrentIM(const QString &im)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(im);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCurrentIM"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> ToggleIM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("ToggleIM"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2011~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
// Qt
|
||||
#include <QDBusArgument>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
// self
|
||||
#include "fcitxqtkeyboardlayout.h"
|
||||
|
||||
const QString& FcitxQtKeyboardLayout::layout() const
|
||||
{
|
||||
return m_layout;
|
||||
}
|
||||
const QString& FcitxQtKeyboardLayout::langCode() const
|
||||
{
|
||||
return m_langCode;
|
||||
}
|
||||
const QString& FcitxQtKeyboardLayout::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const QString& FcitxQtKeyboardLayout::variant() const
|
||||
{
|
||||
return m_variant;
|
||||
}
|
||||
|
||||
void FcitxQtKeyboardLayout::setLayout(const QString& layout)
|
||||
{
|
||||
m_layout = layout;
|
||||
}
|
||||
|
||||
void FcitxQtKeyboardLayout::setLangCode(const QString& lang)
|
||||
{
|
||||
m_langCode = lang;
|
||||
}
|
||||
|
||||
void FcitxQtKeyboardLayout::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void FcitxQtKeyboardLayout::setVariant(const QString& variant)
|
||||
{
|
||||
m_variant = variant;
|
||||
}
|
||||
|
||||
void FcitxQtKeyboardLayout::registerMetaType()
|
||||
{
|
||||
qRegisterMetaType<FcitxQtKeyboardLayout>("FcitxQtKeyboardLayout");
|
||||
qDBusRegisterMetaType<FcitxQtKeyboardLayout>();
|
||||
qRegisterMetaType<FcitxQtKeyboardLayoutList>("FcitxQtKeyboardLayoutList");
|
||||
qDBusRegisterMetaType<FcitxQtKeyboardLayoutList>();
|
||||
}
|
||||
|
||||
FCITXQTDBUSADDONS_EXPORT
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtKeyboardLayout& layout)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << layout.layout();
|
||||
argument << layout.variant();
|
||||
argument << layout.name();
|
||||
argument << layout.langCode();
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
FCITXQTDBUSADDONS_EXPORT
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtKeyboardLayout& layout)
|
||||
{
|
||||
QString l;
|
||||
QString variant;
|
||||
QString name;
|
||||
QString langCode;
|
||||
argument.beginStructure();
|
||||
argument >> l >> variant >> name >> langCode;
|
||||
argument.endStructure();
|
||||
layout.setLayout(l);
|
||||
layout.setVariant(variant);
|
||||
layout.setName(name);
|
||||
layout.setLangCode(langCode);
|
||||
return argument;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2011~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FCITX_QT_KEYBOARD_LAYOUT_H
|
||||
#define FCITX_QT_KEYBOARD_LAYOUT_H
|
||||
|
||||
#include "fcitxqtdbusaddons_export.h"
|
||||
|
||||
// Qt
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtDBus/QDBusArgument>
|
||||
|
||||
class FCITXQTDBUSADDONS_EXPORT FcitxQtKeyboardLayout
|
||||
{
|
||||
public:
|
||||
const QString& layout() const;
|
||||
const QString& variant() const;
|
||||
const QString& name() const;
|
||||
const QString& langCode() const;
|
||||
void setLayout(const QString& layout);
|
||||
void setLangCode(const QString& lang);
|
||||
void setName(const QString& name);
|
||||
void setVariant(const QString& variant);
|
||||
|
||||
static void registerMetaType();
|
||||
private:
|
||||
QString m_layout;
|
||||
QString m_variant;
|
||||
QString m_name;
|
||||
QString m_langCode;
|
||||
};
|
||||
|
||||
typedef QList<FcitxQtKeyboardLayout> FcitxQtKeyboardLayoutList;
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtKeyboardLayout& l);
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtKeyboardLayout& l);
|
||||
|
||||
Q_DECLARE_METATYPE(FcitxQtKeyboardLayout)
|
||||
Q_DECLARE_METATYPE(FcitxQtKeyboardLayoutList)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtkeyboardproxy -c FcitxQtKeyboardProxy interfaces/org.fcitx.Fcitx.Keyboard.xml -i fcitxqtkeyboardlayout.h -i fcitxqt_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "fcitxqtkeyboardproxy.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class FcitxQtKeyboardProxy
|
||||
*/
|
||||
|
||||
FcitxQtKeyboardProxy::FcitxQtKeyboardProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
{
|
||||
}
|
||||
|
||||
FcitxQtKeyboardProxy::~FcitxQtKeyboardProxy()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtkeyboardproxy -c FcitxQtKeyboardProxy interfaces/org.fcitx.Fcitx.Keyboard.xml -i fcitxqtkeyboardlayout.h -i fcitxqt_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef FCITXQTKEYBOARDPROXY_H_1409252990
|
||||
#define FCITXQTKEYBOARDPROXY_H_1409252990
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include "fcitxqtkeyboardlayout.h"
|
||||
#include "fcitxqtdbusaddons_export.h"
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.fcitx.Fcitx.Keyboard
|
||||
*/
|
||||
class FCITXQTDBUSADDONS_EXPORT FcitxQtKeyboardProxy: public QDBusAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.fcitx.Fcitx.Keyboard"; }
|
||||
|
||||
public:
|
||||
FcitxQtKeyboardProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~FcitxQtKeyboardProxy();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<QString, QString> GetLayoutForIM(const QString &im)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(im);
|
||||
return asyncCallWithArgumentList(QLatin1String("GetLayoutForIM"), argumentList);
|
||||
}
|
||||
inline QDBusReply<QString> GetLayoutForIM(const QString &im, QString &variant)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(im);
|
||||
QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("GetLayoutForIM"), argumentList);
|
||||
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
|
||||
variant = qdbus_cast<QString>(reply.arguments().at(1));
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<FcitxQtKeyboardLayoutList> GetLayouts()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("GetLayouts"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetLayoutForIM(const QString &im, const QString &layout, const QString &variant)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(im) << QVariant::fromValue(layout) << QVariant::fromValue(variant);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetLayoutForIM"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.fcitx.Fcitx.InputContext">
|
||||
<method name="EnableIC">
|
||||
</method>
|
||||
<method name="CloseIC">
|
||||
</method>
|
||||
<method name="FocusIn">
|
||||
</method>
|
||||
<method name="FocusOut">
|
||||
</method>
|
||||
<method name="Reset">
|
||||
</method>
|
||||
<method name="MouseEvent">
|
||||
<arg name="x" direction="in" type="i" />
|
||||
</method>
|
||||
<method name="SetCursorLocation">
|
||||
<arg name="x" direction="in" type="i"/>
|
||||
<arg name="y" direction="in" type="i"/>
|
||||
</method>
|
||||
<method name="SetCursorRect">
|
||||
<arg name="x" direction="in" type="i"/>
|
||||
<arg name="y" direction="in" type="i"/>
|
||||
<arg name="w" direction="in" type="i"/>
|
||||
<arg name="h" direction="in" type="i"/>
|
||||
</method>
|
||||
<method name="SetCapacity">
|
||||
<arg name="caps" direction="in" type="u"/>
|
||||
</method>
|
||||
<method name="SetSurroundingText">
|
||||
<arg name="text" direction="in" type="s"/>
|
||||
<arg name="cursor" direction="in" type="u"/>
|
||||
<arg name="anchor" direction="in" type="u"/>
|
||||
</method>
|
||||
<method name="SetSurroundingTextPosition">
|
||||
<arg name="cursor" direction="in" type="u"/>
|
||||
<arg name="anchor" direction="in" type="u"/>
|
||||
</method>
|
||||
<method name="DestroyIC">
|
||||
</method>
|
||||
<method name="ProcessKeyEvent">
|
||||
<arg name="keyval" direction="in" type="u"/>
|
||||
<arg name="keycode" direction="in" type="u"/>
|
||||
<arg name="state" direction="in" type="u"/>
|
||||
<arg name="type" direction="in" type="i"/>
|
||||
<arg name="time" direction="in" type="u"/>
|
||||
<arg name="ret" direction="out" type="i"/>
|
||||
</method>
|
||||
<signal name="EnableIM">
|
||||
</signal>
|
||||
<signal name="CloseIM">
|
||||
</signal>
|
||||
<signal name="CommitString">
|
||||
<arg name="str" type="s"/>
|
||||
</signal>
|
||||
<signal name="UpdateFormattedPreedit">
|
||||
<arg name="str" type="a(si)" />
|
||||
<arg name="cursorpos" type="i"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="FcitxQtFormattedPreeditList" />
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="FcitxQtFormattedPreeditList" />
|
||||
</signal>
|
||||
<signal name="UpdateClientSideUI">
|
||||
<arg name="auxup" type="s"/>
|
||||
<arg name="auxdown" type="s"/>
|
||||
<arg name="preedit" type="s"/>
|
||||
<arg name="candidateword" type="s"/>
|
||||
<arg name="imname" type="s"/>
|
||||
<arg name="cursorpos" type="i"/>
|
||||
</signal>
|
||||
<signal name="ForwardKey">
|
||||
<arg name="keyval" type="u"/>
|
||||
<arg name="state" type="u"/>
|
||||
<arg name="type" type="i"/>
|
||||
</signal>
|
||||
<signal name="DeleteSurroundingText">
|
||||
<arg name="offset" type="i"/>
|
||||
<arg name="nchar" type="u"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.fcitx.Fcitx.InputMethod">
|
||||
<method name="CreateIC">
|
||||
<arg name="icid" direction="out" type="i"/>
|
||||
<arg name="keyval1" direction="out" type="u"/>
|
||||
<arg name="state1" direction="out" type="u"/>
|
||||
<arg name="keyval2" direction="out" type="u"/>
|
||||
<arg name="state2" direction="out" type="u"/>
|
||||
</method>
|
||||
<method name="CreateICv2">
|
||||
<arg name="appname" direction="in" type="s"/>
|
||||
<arg name="icid" direction="out" type="i"/>
|
||||
<arg name="enable" direction="out" type="b"/>
|
||||
<arg name="keyval1" direction="out" type="u"/>
|
||||
<arg name="state1" direction="out" type="u"/>
|
||||
<arg name="keyval2" direction="out" type="u"/>
|
||||
<arg name="state2" direction="out" type="u"/>
|
||||
</method>
|
||||
<method name="CreateICv3">
|
||||
<arg name="appname" direction="in" type="s"/>
|
||||
<arg name="pid" direction="in" type="i"/>
|
||||
<arg name="icid" direction="out" type="i"/>
|
||||
<arg name="enable" direction="out" type="b"/>
|
||||
<arg name="keyval1" direction="out" type="u"/>
|
||||
<arg name="state1" direction="out" type="u"/>
|
||||
<arg name="keyval2" direction="out" type="u"/>
|
||||
<arg name="state2" direction="out" type="u"/>
|
||||
</method>
|
||||
<method name="Exit">
|
||||
</method>
|
||||
<method name="GetCurrentIM">
|
||||
<arg name="im" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="SetCurrentIM">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="ReloadConfig">
|
||||
</method>
|
||||
<method name="ReloadAddonConfig">
|
||||
<arg name="addon" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="Restart">
|
||||
</method>
|
||||
<method name="Configure">
|
||||
</method>
|
||||
<method name="ConfigureAddon">
|
||||
<arg name="addon" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="ConfigureIM">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="GetCurrentUI">
|
||||
<arg name="addon" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="GetIMAddon">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
<arg name="addon" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="ActivateIM">
|
||||
</method>
|
||||
<method name="InactivateIM">
|
||||
</method>
|
||||
<method name="ToggleIM">
|
||||
</method>
|
||||
<method name="ResetIMList">
|
||||
</method>
|
||||
<method name="GetCurrentState">
|
||||
<arg name="state" direction="out" type="i"/>
|
||||
</method>
|
||||
<property access="readwrite" type="a(sssb)" name="IMList">
|
||||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName" value="FcitxQtInputMethodItemList" />
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="FcitxQtInputMethodItemList" />
|
||||
</property>
|
||||
<property access="readwrite" type="s" name="CurrentIM">
|
||||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
|
||||
</property>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.fcitx.Fcitx.Keyboard">
|
||||
<method name="GetLayouts">
|
||||
<arg name="layouts" direction="out" type="a(ssss)"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="FcitxQtKeyboardLayoutList" />
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="FcitxQtKeyboardLayoutList" />
|
||||
</method>
|
||||
<method name="GetLayoutForIM">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
<arg name="layout" direction="out" type="s"/>
|
||||
<arg name="variant" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="SetLayoutForIM">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
<arg name="layout" direction="in" type="s"/>
|
||||
<arg name="variant" direction="in" type="s"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright (C) 2001 Ellis Whitehead <ellis@kde.org>
|
||||
|
||||
Win32 port:
|
||||
Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KEYSERVER_X11_H
|
||||
#define KEYSERVER_X11_H
|
||||
|
||||
#include <X11/keysym.h>
|
||||
|
||||
struct TransKey {
|
||||
int keySymQt;
|
||||
uint keySymX;
|
||||
};
|
||||
|
||||
static const TransKey g_rgQtToSymX[] = {
|
||||
{ Qt::Key_Escape, XK_Escape },
|
||||
{ Qt::Key_Tab, XK_Tab },
|
||||
{ Qt::Key_Backtab, XK_ISO_Left_Tab },
|
||||
{ Qt::Key_Backspace, XK_BackSpace },
|
||||
{ Qt::Key_Return, XK_Return },
|
||||
{ Qt::Key_Enter, XK_KP_Enter },
|
||||
{ Qt::Key_Insert, XK_Insert },
|
||||
{ Qt::Key_Delete, XK_Delete },
|
||||
{ Qt::Key_Pause, XK_Pause },
|
||||
#ifdef sun
|
||||
{ Qt::Key_Print, XK_F22 },
|
||||
#else
|
||||
{ Qt::Key_Print, XK_Print },
|
||||
#endif
|
||||
{ Qt::Key_SysReq, XK_Sys_Req },
|
||||
{ Qt::Key_Home, XK_Home },
|
||||
{ Qt::Key_End, XK_End },
|
||||
{ Qt::Key_Left, XK_Left },
|
||||
{ Qt::Key_Up, XK_Up },
|
||||
{ Qt::Key_Right, XK_Right },
|
||||
{ Qt::Key_Down, XK_Down },
|
||||
//{ Qt::Key_Shift, 0 },
|
||||
//{ Qt::Key_Control, 0 },
|
||||
//{ Qt::Key_Meta, 0 },
|
||||
//{ Qt::Key_Alt, 0 },
|
||||
{ Qt::Key_CapsLock, XK_Caps_Lock },
|
||||
{ Qt::Key_NumLock, XK_Num_Lock },
|
||||
{ Qt::Key_ScrollLock, XK_Scroll_Lock },
|
||||
{ Qt::Key_F1, XK_F1 },
|
||||
{ Qt::Key_F2, XK_F2 },
|
||||
{ Qt::Key_F3, XK_F3 },
|
||||
{ Qt::Key_F4, XK_F4 },
|
||||
{ Qt::Key_F5, XK_F5 },
|
||||
{ Qt::Key_F6, XK_F6 },
|
||||
{ Qt::Key_F7, XK_F7 },
|
||||
{ Qt::Key_F8, XK_F8 },
|
||||
{ Qt::Key_F9, XK_F9 },
|
||||
{ Qt::Key_F10, XK_F10 },
|
||||
{ Qt::Key_F11, XK_F11 },
|
||||
{ Qt::Key_F12, XK_F12 },
|
||||
{ Qt::Key_F13, XK_F13 },
|
||||
{ Qt::Key_F14, XK_F14 },
|
||||
{ Qt::Key_F15, XK_F15 },
|
||||
{ Qt::Key_F16, XK_F16 },
|
||||
{ Qt::Key_F17, XK_F17 },
|
||||
{ Qt::Key_F18, XK_F18 },
|
||||
{ Qt::Key_F19, XK_F19 },
|
||||
{ Qt::Key_F20, XK_F20 },
|
||||
{ Qt::Key_F21, XK_F21 },
|
||||
{ Qt::Key_F22, XK_F22 },
|
||||
{ Qt::Key_F23, XK_F23 },
|
||||
{ Qt::Key_F24, XK_F24 },
|
||||
{ Qt::Key_F25, XK_F25 },
|
||||
{ Qt::Key_F26, XK_F26 },
|
||||
{ Qt::Key_F27, XK_F27 },
|
||||
{ Qt::Key_F28, XK_F28 },
|
||||
{ Qt::Key_F29, XK_F29 },
|
||||
{ Qt::Key_F30, XK_F30 },
|
||||
{ Qt::Key_F31, XK_F31 },
|
||||
{ Qt::Key_F32, XK_F32 },
|
||||
{ Qt::Key_F33, XK_F33 },
|
||||
{ Qt::Key_F34, XK_F34 },
|
||||
{ Qt::Key_F35, XK_F35 },
|
||||
{ Qt::Key_Super_L, XK_Super_L },
|
||||
{ Qt::Key_Super_R, XK_Super_R },
|
||||
{ Qt::Key_Menu, XK_Menu },
|
||||
{ Qt::Key_Hyper_L, XK_Hyper_L },
|
||||
{ Qt::Key_Hyper_R, XK_Hyper_R },
|
||||
{ Qt::Key_Help, XK_Help },
|
||||
|
||||
{ '/', XK_KP_Divide },
|
||||
{ '*', XK_KP_Multiply },
|
||||
{ '-', XK_KP_Subtract },
|
||||
{ '+', XK_KP_Add },
|
||||
{ Qt::Key_Return, XK_KP_Enter },
|
||||
{Qt::Key_Multi_key, XK_Multi_key},
|
||||
{Qt::Key_Codeinput, XK_Codeinput},
|
||||
{Qt::Key_SingleCandidate, XK_SingleCandidate},
|
||||
{Qt::Key_MultipleCandidate, XK_MultipleCandidate},
|
||||
{Qt::Key_PreviousCandidate, XK_PreviousCandidate},
|
||||
{Qt::Key_Mode_switch, XK_Mode_switch},
|
||||
{Qt::Key_Kanji, XK_Kanji},
|
||||
{Qt::Key_Muhenkan, XK_Muhenkan},
|
||||
{Qt::Key_Henkan, XK_Henkan},
|
||||
{Qt::Key_Romaji, XK_Romaji},
|
||||
{Qt::Key_Hiragana, XK_Hiragana},
|
||||
{Qt::Key_Katakana, XK_Katakana},
|
||||
{Qt::Key_Hiragana_Katakana, XK_Hiragana_Katakana},
|
||||
{Qt::Key_Zenkaku, XK_Zenkaku},
|
||||
{Qt::Key_Hankaku, XK_Hankaku},
|
||||
{Qt::Key_Zenkaku_Hankaku, XK_Zenkaku_Hankaku},
|
||||
{Qt::Key_Touroku, XK_Touroku},
|
||||
{Qt::Key_Massyo, XK_Massyo},
|
||||
{Qt::Key_Kana_Lock, XK_Kana_Lock},
|
||||
{Qt::Key_Kana_Shift, XK_Kana_Shift},
|
||||
{Qt::Key_Eisu_Shift, XK_Eisu_Shift},
|
||||
{Qt::Key_Eisu_toggle, XK_Eisu_toggle},
|
||||
{Qt::Key_Hangul, XK_Hangul},
|
||||
{Qt::Key_Hangul_Start, XK_Hangul_Start},
|
||||
{Qt::Key_Hangul_End, XK_Hangul_End},
|
||||
{Qt::Key_Hangul_Hanja, XK_Hangul_Hanja},
|
||||
{Qt::Key_Hangul_Jamo, XK_Hangul_Jamo},
|
||||
{Qt::Key_Hangul_Romaja, XK_Hangul_Romaja},
|
||||
{Qt::Key_Hangul_Jeonja, XK_Hangul_Jeonja},
|
||||
{Qt::Key_Hangul_Banja, XK_Hangul_Banja},
|
||||
{Qt::Key_Hangul_PreHanja, XK_Hangul_PreHanja},
|
||||
{Qt::Key_Hangul_PostHanja, XK_Hangul_PostHanja},
|
||||
{Qt::Key_Hangul_Special, XK_Hangul_Special},
|
||||
};
|
||||
|
||||
#include <qstring.h>
|
||||
|
||||
inline int map_sym_to_qt(uint keySym)
|
||||
{
|
||||
if (keySym < 0x1000) {
|
||||
if (keySym >= 'a' && keySym <= 'z')
|
||||
return QChar(keySym).toUpper().unicode();
|
||||
return keySym;
|
||||
}
|
||||
#ifdef Q_WS_WIN
|
||||
if (keySym < 0x3000)
|
||||
return keySym;
|
||||
#else
|
||||
if (keySym < 0x3000)
|
||||
return keySym | Qt::UNICODE_ACCEL;
|
||||
|
||||
for (uint i = 0; i < sizeof(g_rgQtToSymX) / sizeof(TransKey); i++)
|
||||
if (g_rgQtToSymX[i].keySymX == keySym)
|
||||
return g_rgQtToSymX[i].keySymQt;
|
||||
#endif
|
||||
return Qt::Key_unknown;
|
||||
}
|
||||
|
||||
static bool symToKeyQt(uint keySym, int& keyQt)
|
||||
{
|
||||
keyQt = map_sym_to_qt(keySym);
|
||||
return (keyQt != Qt::Key_unknown);
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user