From 30c9bcb985dfbbd5d6705f7d2c83a546e85829a4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 11 Jan 2017 09:30:51 +0400 Subject: [PATCH] Alpha 0.10.27: appoint admins in your supergroups from context menu. --- Telegram/Resources/langs/lang.strings | 4 + Telegram/Resources/langs/lang_de.strings | 4 + Telegram/Resources/langs/lang_es.strings | 8 +- Telegram/Resources/langs/lang_it.strings | 6 +- Telegram/Resources/langs/lang_ko.strings | 4 + Telegram/Resources/langs/lang_nl.strings | 4 + Telegram/Resources/langs/lang_pt_BR.strings | 4 + Telegram/Resources/winrc/Telegram.rc | 8 +- Telegram/Resources/winrc/Updater.rc | 8 +- Telegram/SourceFiles/application.cpp | 4 +- Telegram/SourceFiles/core/version.h | 4 +- Telegram/SourceFiles/dialogswidget.cpp | 2 +- Telegram/SourceFiles/historywidget.cpp | 3 +- Telegram/SourceFiles/mainwindow.cpp | 2 +- Telegram/SourceFiles/mediaview.cpp | 2 +- Telegram/SourceFiles/overviewwidget.cpp | 4 +- .../profile/profile_block_group_members.cpp | 108 ++++++++++++++++-- .../profile/profile_block_group_members.h | 5 + .../profile/profile_block_peer_list.cpp | 51 ++++++++- .../profile/profile_block_peer_list.h | 11 ++ .../SourceFiles/ui/widgets/input_fields.cpp | 10 +- Telegram/SourceFiles/ui/widgets/labels.cpp | 2 +- .../SourceFiles/ui/widgets/popup_menu.cpp | 7 +- Telegram/SourceFiles/ui/widgets/popup_menu.h | 10 +- Telegram/build/version | 6 +- 25 files changed, 233 insertions(+), 48 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 8dc0ed77c..77c9b8a9d 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -851,6 +851,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_pin_to_top" = "Pin to top"; "lng_context_unpin_from_top" = "Unpin from top"; +"lng_context_promote_admin" = "Promote to admin"; +"lng_context_remove_admin" = "Remove from admins"; +"lng_context_remove_from_group" = "Remove from group"; + "lng_context_copy_link" = "Copy Link"; "lng_context_copy_post_link" = "Copy Post Link"; "lng_context_copy_email" = "Copy Email Address"; diff --git a/Telegram/Resources/langs/lang_de.strings b/Telegram/Resources/langs/lang_de.strings index 68ebf98af..e8042d615 100644 --- a/Telegram/Resources/langs/lang_de.strings +++ b/Telegram/Resources/langs/lang_de.strings @@ -851,6 +851,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_pin_to_top" = "Anheften"; "lng_context_unpin_from_top" = "Entfernen"; +"lng_context_promote_admin" = "Zum Admin machen"; +"lng_context_remove_admin" = "Als Admin entfernen"; +"lng_context_remove_from_group" = "Aus Gruppe entfernen"; + "lng_context_copy_link" = "Link kopieren"; "lng_context_copy_post_link" = "Nachrichtenlink kopieren"; "lng_context_copy_email" = "E-Mail-Adresse kopieren"; diff --git a/Telegram/Resources/langs/lang_es.strings b/Telegram/Resources/langs/lang_es.strings index 4ba8145fb..1126e5f96 100644 --- a/Telegram/Resources/langs/lang_es.strings +++ b/Telegram/Resources/langs/lang_es.strings @@ -851,8 +851,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_pin_to_top" = "Anclar"; "lng_context_unpin_from_top" = "Desanclar"; +"lng_context_promote_admin" = "Nombrar administrador"; +"lng_context_remove_admin" = "Eliminar de los administradores"; +"lng_context_remove_from_group" = "Eliminar del grupo"; + "lng_context_copy_link" = "Copiar enlace"; -"lng_context_copy_post_link" = "Copiar enlace"; +"lng_context_copy_post_link" = "Copiar enlace de la publicación"; "lng_context_copy_email" = "Copiar e-mail"; "lng_context_copy_hashtag" = "Copiar hashtag"; "lng_context_copy_mention" = "Copiar alias"; @@ -919,7 +923,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_reply_cant_forward" = "Lo sentimos, no puedes responder un mensaje viejo en un supergrupo :( ¿Quieres reenviarlo y añadir un comentario?"; "lng_share_title" = "Compartir con"; -"lng_share_copy_link" = "Copiar enlace"; +"lng_share_copy_link" = "Copiar enlace para compartir"; "lng_share_confirm" = "Enviar"; "lng_share_wrong_user" = "Este juego fue abierto por un usuario diferente."; "lng_share_game_link_copied" = "Enlace del juego copiado al portapapeles."; diff --git a/Telegram/Resources/langs/lang_it.strings b/Telegram/Resources/langs/lang_it.strings index 4b9da5cca..96ddc1613 100644 --- a/Telegram/Resources/langs/lang_it.strings +++ b/Telegram/Resources/langs/lang_it.strings @@ -33,7 +33,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_open_from_tray" = "Apri Telegram"; "lng_minimize_to_tray" = "Riduci a icona"; "lng_quit_from_tray" = "Chiudi Telegram"; -"lng_tray_icon_text" = "Telegram è ancora attivo qui,\npuoi cambiarlo nelle impostazioni.\nSe l'icona scompare dall'area di notifica,\npuoi ripristinarla dalle icone nascoste."; +"lng_tray_icon_text" = "Telegram è ancora attivo qui,\npuoi cambiarlo nelle impostazioni.\nSe l'icona di notifica scompare,\npuoi ripristinarla dalle icone nascoste."; "lng_month1" = "Gennaio"; "lng_month2" = "Febbraio"; @@ -851,6 +851,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_pin_to_top" = "Fissa in alto"; "lng_context_unpin_from_top" = "Togli dall'alto"; +"lng_context_promote_admin" = "Rendi amministratore"; +"lng_context_remove_admin" = "Rimuovi dagli amministratori"; +"lng_context_remove_from_group" = "Rimuovi dal gruppo"; + "lng_context_copy_link" = "Copia link"; "lng_context_copy_post_link" = "Copia link post"; "lng_context_copy_email" = "Copia indirizzo email"; diff --git a/Telegram/Resources/langs/lang_ko.strings b/Telegram/Resources/langs/lang_ko.strings index cf479795c..83b890e8b 100644 --- a/Telegram/Resources/langs/lang_ko.strings +++ b/Telegram/Resources/langs/lang_ko.strings @@ -851,6 +851,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_pin_to_top" = "상단에 고정"; "lng_context_unpin_from_top" = "상단에서 고정해제"; +"lng_context_promote_admin" = "관리자로 지정"; +"lng_context_remove_admin" = "관리자에서 제외"; +"lng_context_remove_from_group" = "그룹에서 추방"; + "lng_context_copy_link" = "링크 복사"; "lng_context_copy_post_link" = "메시지 링크 복사"; "lng_context_copy_email" = "이메일 복사"; diff --git a/Telegram/Resources/langs/lang_nl.strings b/Telegram/Resources/langs/lang_nl.strings index 8191fd499..b1f81ed53 100644 --- a/Telegram/Resources/langs/lang_nl.strings +++ b/Telegram/Resources/langs/lang_nl.strings @@ -851,6 +851,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_pin_to_top" = "Vastzetten"; "lng_context_unpin_from_top" = "Losmaken"; +"lng_context_promote_admin" = "Beheerder maken"; +"lng_context_remove_admin" = "Ontslaan als beheerder"; +"lng_context_remove_from_group" = "Uit de groep verwijderen"; + "lng_context_copy_link" = "Link kopiëren"; "lng_context_copy_post_link" = "Berichtlink kopiëren"; "lng_context_copy_email" = "E-mailadres kopiëren"; diff --git a/Telegram/Resources/langs/lang_pt_BR.strings b/Telegram/Resources/langs/lang_pt_BR.strings index ab51e82d4..353723c8d 100644 --- a/Telegram/Resources/langs/lang_pt_BR.strings +++ b/Telegram/Resources/langs/lang_pt_BR.strings @@ -851,6 +851,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_context_pin_to_top" = "Fixar no topo"; "lng_context_unpin_from_top" = "Desafixar do topo"; +"lng_context_promote_admin" = "Promover a administrador"; +"lng_context_remove_admin" = "Remover dos administradores"; +"lng_context_remove_from_group" = "Remover do grupo"; + "lng_context_copy_link" = "Copiar Link"; "lng_context_copy_post_link" = "Copiar Link do Post"; "lng_context_copy_email" = "Copiar Endereço de Email"; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index b02cbaa0c..10d1567bb 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,26,0 - PRODUCTVERSION 0,10,26,0 + FILEVERSION 0,10,27,0 + PRODUCTVERSION 0,10,27,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.26.0" + VALUE "FileVersion", "0.10.27.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.26.0" + VALUE "ProductVersion", "0.10.27.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index e16d08ab3..5bec209f2 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,26,0 - PRODUCTVERSION 0,10,26,0 + FILEVERSION 0,10,27,0 + PRODUCTVERSION 0,10,27,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,10 +43,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram Messenger LLP" VALUE "FileDescription", "Telegram Updater" - VALUE "FileVersion", "0.10.26.0" + VALUE "FileVersion", "0.10.27.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.26.0" + VALUE "ProductVersion", "0.10.27.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 01ee6d7fa..a7f244cf8 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -1069,8 +1069,8 @@ void AppClass::checkMapVersion() { if (Local::oldMapVersion() < AppVersion) { if (Local::oldMapVersion()) { QString versionFeatures; - if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10026) { - versionFeatures = QString::fromUtf8("\xe2\x80\x94 You can use t.me instead of telegram.me\n\xe2\x80\x94 OpenAL updated to the latest version\n\xe2\x80\x94 Bug fixes and other minor improvements"); + if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10027) { + versionFeatures = QString::fromUtf8("\xe2\x80\x94 Appoint admins in your supergroups from members list context menu\n\xe2\x80\x94 Bug fixes and other minor improvements"); } else if (!(cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10018) { versionFeatures = langNewVersionText(); } else { diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 77da273ca..e623144c2 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10026; -constexpr str_const AppVersionStr = "0.10.26"; +constexpr int AppVersion = 10027; +constexpr str_const AppVersionStr = "0.10.27"; constexpr bool AppAlphaVersion = true; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index ed0c3a43e..b14918268 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -863,7 +863,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { mousePressReleased(_pressButton); } - _menu = new Ui::PopupMenu(); + _menu = new Ui::PopupMenu(nullptr); App::main()->fillPeerMenu(_menuPeer, [this](const QString &text, base::lambda &&callback) { return _menu->addAction(text, std_::move(callback)); }, true); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 75433a908..8df16a1e9 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -1229,7 +1229,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { isUponSelected = hasSelected; } - _menu = new Ui::PopupMenu(); + _menu = new Ui::PopupMenu(nullptr); _contextMenuLnk = ClickHandler::getActive(); HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem(); @@ -2988,6 +2988,7 @@ void SilentToggle::setChecked(bool checked) { } void SilentToggle::leaveEvent(QEvent *e) { + IconButton::leaveEvent(e); Ui::Tooltip::Hide(); } diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 940e34c27..c7cc05f60 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -177,7 +177,7 @@ void MainWindow::onWindowActiveChanged() { void MainWindow::firstShow() { #ifdef Q_OS_WIN - trayIconMenu = new Ui::PopupMenu(); + trayIconMenu = new Ui::PopupMenu(nullptr); trayIconMenu->deleteOnHide(false); #else // Q_OS_WIN trayIconMenu = new QMenu(this); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index db93672f2..f1c4eac60 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -2534,7 +2534,7 @@ void MediaView::contextMenuEvent(QContextMenuEvent *e) { _menu->deleteLater(); _menu = 0; } - _menu = new Ui::PopupMenu(st::mediaviewPopupMenu); + _menu = new Ui::PopupMenu(nullptr, st::mediaviewPopupMenu); updateActions(); for_const (auto &action, _actions) { _menu->addAction(action.text, this, action.member)->setEnabled(true); diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index eb61b60de..a86560021 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -1205,7 +1205,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { bool lnkIsAudio = lnkDocument ? (lnkDocument->document()->voice() != nullptr) : false; bool lnkIsSong = lnkDocument ? (lnkDocument->document()->song() != nullptr) : false; if (lnkPhoto || lnkDocument) { - _menu = new Ui::PopupMenu(); + _menu = new Ui::PopupMenu(nullptr); if (App::hoveredLinkItem()) { _menu->addAction(lang(lng_context_to_msg), this, SLOT(goToMessage()))->setEnabled(true); } @@ -1251,7 +1251,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { repaintItem(App::contextItem()); if (_selectedMsgId) repaintItem(_selectedMsgId, -1); } else if (!ignoreMousedItem && App::mousedItem() && App::mousedItem()->channelId() == itemChannel(_mousedItem) && App::mousedItem()->id == itemMsgId(_mousedItem)) { - _menu = new Ui::PopupMenu(); + _menu = new Ui::PopupMenu(nullptr); QString linkCopyToClipboardText = _contextMenuLnk ? _contextMenuLnk->copyToClipboardContextItemText() : QString(); if (!linkCopyToClipboardText.isEmpty()) { _menu->addAction(linkCopyToClipboardText, this, SLOT(copyContextUrl()))->setEnabled(true); diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.cpp b/Telegram/SourceFiles/profile/profile_block_group_members.cpp index ba51b5ee3..f3cf25ce7 100644 --- a/Telegram/SourceFiles/profile/profile_block_group_members.cpp +++ b/Telegram/SourceFiles/profile/profile_block_group_members.cpp @@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_profile.h" #include "ui/widgets/labels.h" #include "boxes/confirmbox.h" +#include "ui/widgets/popup_menu.h" #include "mainwidget.h" #include "apiwrap.h" #include "observer_peer.h" @@ -50,16 +51,7 @@ GroupMembersWidget::GroupMembersWidget(QWidget *parent, PeerData *peer, TitleVis })); setRemovedCallback([this, peer](PeerData *selectedPeer) { - auto user = selectedPeer->asUser(); - auto text = lng_profile_sure_kick(lt_user, user->firstName); - Ui::show(Box(text, lang(lng_box_remove), base::lambda_guarded(this, [peer, user] { - Ui::hideLayer(); - if (auto chat = peer->asChat()) { - if (App::main()) App::main()->kickParticipant(chat, user); - } else if (auto channel = peer->asChannel()) { - if (App::api()) App::api()->kickParticipant(channel, user); - } - }))); + removePeer(selectedPeer); }); setSelectedCallback([this](PeerData *selectedPeer) { Ui::showPeerProfile(selectedPeer); @@ -74,6 +66,59 @@ GroupMembersWidget::GroupMembersWidget(QWidget *parent, PeerData *peer, TitleVis refreshMembers(); } +void GroupMembersWidget::addAdmin(PeerData *selectedPeer) { + auto user = selectedPeer->asUser(); + auto text = lng_channel_admin_sure(lt_user, user->firstName); + Ui::show(Box(text, base::lambda_guarded(this, [this, user] { + Ui::hideLayer(); + if (auto chat = peer()->asChat()) { + // not supported + } else if (auto channel = peer()->asMegagroup()) { + MTP::send(MTPchannels_EditAdmin(channel->inputChannel, user->inputUser, MTP_channelRoleEditor()), rpcDone(base::lambda_guarded(this, [this, channel, user](const MTPUpdates &result) { + if (App::main()) App::main()->sentUpdatesReceived(result); + channel->mgInfo->lastAdmins.insert(user); + channel->setAdminsCount(channel->adminsCount() + 1); + if (App::main()) emit App::main()->peerUpdated(channel); + Notify::peerUpdatedDelayed(channel, Notify::PeerUpdate::Flag::AdminsChanged); + }))); + } + }))); +} + +void GroupMembersWidget::removeAdmin(PeerData *selectedPeer) { + auto user = selectedPeer->asUser(); + auto text = lng_profile_sure_kick_admin(lt_user, user->firstName); + Ui::show(Box(text, lang(lng_box_remove), base::lambda_guarded(this, [this, user] { + Ui::hideLayer(); + if (auto chat = peer()->asChat()) { + // not supported + } else if (auto channel = peer()->asMegagroup()) { + MTP::send(MTPchannels_EditAdmin(channel->inputChannel, user->inputUser, MTP_channelRoleEmpty()), rpcDone(base::lambda_guarded(this, [this, channel, user](const MTPUpdates &result) { + if (App::main()) App::main()->sentUpdatesReceived(result); + channel->mgInfo->lastAdmins.remove(user); + if (channel->adminsCount() > 1) { + channel->setAdminsCount(channel->adminsCount() - 1); + if (App::main()) emit App::main()->peerUpdated(channel); + } + Notify::peerUpdatedDelayed(channel, Notify::PeerUpdate::Flag::AdminsChanged); + }))); + } + }))); +} + +void GroupMembersWidget::removePeer(PeerData *selectedPeer) { + auto user = selectedPeer->asUser(); + auto text = lng_profile_sure_kick(lt_user, user->firstName); + Ui::show(Box(text, lang(lng_box_remove), base::lambda_guarded(this, [user, peer = peer()] { + Ui::hideLayer(); + if (auto chat = peer->asChat()) { + if (App::main()) App::main()->kickParticipant(chat, user); + } else if (auto channel = peer->asChannel()) { + if (App::api()) App::api()->kickParticipant(channel, user); + } + }))); +} + void GroupMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { if (update.peer != peer()) { if (update.flags & UpdateFlag::UserOnlineChanged) { @@ -152,6 +197,49 @@ void GroupMembersWidget::paintContents(Painter &p) { PeerListWidget::paintContents(p); } +Ui::PopupMenu *GroupMembersWidget::fillPeerMenu(PeerData *selectedPeer) { + if (emptyTitle()) { + return nullptr; + } + auto result = new Ui::PopupMenu(nullptr); + result->addAction(lang(lng_context_view_profile), [selectedPeer] { + Ui::showPeerProfile(selectedPeer); + }); + auto chat = peer()->asChat(); + auto channel = peer()->asMegagroup(); + for_const (auto item, items()) { + if (item->peer == selectedPeer) { + auto canRemoveAdmin = [item, chat, channel] { + if (item->hasAdminStar && !item->peer->isSelf()) { + if (chat) { + // Adding of admins from context menu of chat participants + // is not supported, so the removing is also disabled. + return false;//chat->amCreator(); + } else if (channel) { + return channel->amCreator(); + } + } + return false; + }; + if (channel && channel->amCreator() && !item->hasAdminStar) { + result->addAction(lang(lng_context_promote_admin), base::lambda_guarded(this, [this, selectedPeer] { + addAdmin(selectedPeer); + })); + } else if (canRemoveAdmin()) { + result->addAction(lang(lng_context_remove_admin), base::lambda_guarded(this, [this, selectedPeer] { + removeAdmin(selectedPeer); + })); + } + if (item->hasRemoveLink) { + result->addAction(lang(lng_context_remove_from_group), base::lambda_guarded(this, [this, selectedPeer] { + removePeer(selectedPeer); + })); + } + } + } + return result; +} + void GroupMembersWidget::updateItemStatusText(Item *item) { auto member = getMember(item); auto user = member->user(); diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.h b/Telegram/SourceFiles/profile/profile_block_group_members.h index 4d03e5e88..97da86bf5 100644 --- a/Telegram/SourceFiles/profile/profile_block_group_members.h +++ b/Telegram/SourceFiles/profile/profile_block_group_members.h @@ -55,6 +55,8 @@ protected: void paintContents(Painter &p) override; + Ui::PopupMenu *fillPeerMenu(PeerData *peer) override; + signals: void onlineCountUpdated(int onlineCount); @@ -65,6 +67,9 @@ private: // Observed notifications. void notifyPeerUpdated(const Notify::PeerUpdate &update); + void addAdmin(PeerData *selectedPeer); + void removeAdmin(PeerData *selectedPeer); + void removePeer(PeerData *selectedPeer); void refreshMembers(); void fillChatMembers(ChatData *chat); void fillMegagroupMembers(ChannelData *megagroup); diff --git a/Telegram/SourceFiles/profile/profile_block_peer_list.cpp b/Telegram/SourceFiles/profile/profile_block_peer_list.cpp index c4ddcc820..ad2cfdd6c 100644 --- a/Telegram/SourceFiles/profile/profile_block_peer_list.cpp +++ b/Telegram/SourceFiles/profile/profile_block_peer_list.cpp @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "profile/profile_block_peer_list.h" #include "ui/effects/ripple_animation.h" +#include "ui/widgets/popup_menu.h" #include "styles/style_profile.h" #include "styles/style_widgets.h" @@ -70,7 +71,7 @@ void PeerListWidget::paintContents(Painter &p) { auto to = ceilclamp(_visibleBottom - top, st::profileMemberHeight, 0, _items.size()); for (auto i = from; i < to; ++i) { auto y = top + i * st::profileMemberHeight; - auto selected = (_pressed >= 0) ? (i == _pressed) : (i == _selected); + auto selected = (_menuRowIndex >= 0) ? (i == _menuRowIndex) : (_pressed >= 0) ? (i == _pressed) : (i == _selected); auto selectedRemove = selected && _selectedRemove; if (_pressed >= 0 && !_pressedRemove) { selectedRemove = false; @@ -144,6 +145,7 @@ void PeerListWidget::mousePressEvent(QMouseEvent *e) { _mousePosition = e->globalPos(); updateSelection(); + _pressButton = e->button(); _pressed = _selected; _pressedRemove = _selectedRemove; if (_pressed >= 0 && !_pressedRemove) { @@ -162,9 +164,10 @@ void PeerListWidget::mousePressEvent(QMouseEvent *e) { } void PeerListWidget::mouseReleaseEvent(QMouseEvent *e) { - _mousePosition = e->globalPos(); - updateSelection(); + mousePressReleased(e->button()); +} +void PeerListWidget::mousePressReleased(Qt::MouseButton button) { repaintRow(_pressed); auto pressed = base::take(_pressed, -1); auto pressedRemove = base::take(_pressedRemove); @@ -172,7 +175,7 @@ void PeerListWidget::mouseReleaseEvent(QMouseEvent *e) { if (auto &ripple = _items[pressed]->ripple) { ripple->lastStop(); } - if (pressed == _selected && pressedRemove == _selectedRemove) { + if (pressed == _selected && pressedRemove == _selectedRemove && button == Qt::LeftButton) { if (auto &callback = (pressedRemove ? _removedCallback : _selectedCallback)) { callback(_items[pressed]->peer); } @@ -182,6 +185,46 @@ void PeerListWidget::mouseReleaseEvent(QMouseEvent *e) { repaintSelectedRow(); } +void PeerListWidget::contextMenuEvent(QContextMenuEvent *e) { + if (_menu) { + _menu->deleteLater(); + _menu = nullptr; + } + if (_menuRowIndex >= 0) { + repaintRow(_menuRowIndex); + _menuRowIndex = -1; + } + + if (e->reason() == QContextMenuEvent::Mouse) { + _mousePosition = e->globalPos(); + updateSelection(); + } + + _menuRowIndex = _selected; + if (_pressButton != Qt::LeftButton) { + mousePressReleased(_pressButton); + } + + if (_selected < 0 || _selected >= _items.size()) { + return; + } + + _menu = fillPeerMenu(_items[_selected]->peer); + if (_menu) { + _menu->setDestroyedCallback(base::lambda_guarded(this, [this, menu = _menu] { + if (_menu == menu) { + _menu = nullptr; + } + repaintRow(_menuRowIndex); + _menuRowIndex = -1; + _mousePosition = QCursor::pos(); + updateSelection(); + })); + _menu->popup(e->globalPos()); + e->accept(); + } +} + void PeerListWidget::enterEvent(QEvent *e) { _mousePosition = QCursor::pos(); updateSelection(); diff --git a/Telegram/SourceFiles/profile/profile_block_peer_list.h b/Telegram/SourceFiles/profile/profile_block_peer_list.h index 090d89c5c..1a5e3ba89 100644 --- a/Telegram/SourceFiles/profile/profile_block_peer_list.h +++ b/Telegram/SourceFiles/profile/profile_block_peer_list.h @@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Ui { class RippleAnimation; +class PopupMenu; } // namespace Ui namespace Notify { @@ -105,6 +106,7 @@ protected: void mouseMoveEvent(QMouseEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; + void contextMenuEvent(QContextMenuEvent *e) override; void enterEvent(QEvent *e) override; void enterFromChildEvent(QEvent *e, QWidget *child) override { enterEvent(e); @@ -114,7 +116,12 @@ protected: leaveEvent(e); } + virtual Ui::PopupMenu *fillPeerMenu(PeerData *peer) { + return nullptr; + } + private: + void mousePressReleased(Qt::MouseButton button); void updateSelection(); void setSelected(int selected, bool selectedRemove); void repaintSelectedRow(); @@ -138,6 +145,7 @@ private: int _selected = -1; int _pressed = -1; + Qt::MouseButton _pressButton = Qt::LeftButton; bool _selectedRemove = false; bool _pressedRemove = false; QPoint _mousePosition; @@ -145,6 +153,9 @@ private: QString _removeText; int _removeWidth = 0; + Ui::PopupMenu *_menu = nullptr; + int _menuRowIndex = -1; + }; } // namespace Profile diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.cpp b/Telegram/SourceFiles/ui/widgets/input_fields.cpp index bb41169e4..2d03d08f8 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.cpp +++ b/Telegram/SourceFiles/ui/widgets/input_fields.cpp @@ -1452,7 +1452,7 @@ void FlatTextarea::dropEvent(QDropEvent *e) { void FlatTextarea::contextMenuEvent(QContextMenuEvent *e) { if (auto menu = createStandardContextMenu()) { - (new Ui::PopupMenu(menu))->popup(e->globalPos()); + (new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos()); } } @@ -1620,7 +1620,7 @@ void FlatInput::updatePlaceholderText() { void FlatInput::contextMenuEvent(QContextMenuEvent *e) { if (auto menu = createStandardContextMenu()) { - (new Ui::PopupMenu(menu))->popup(e->globalPos()); + (new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos()); } } @@ -2409,7 +2409,7 @@ void InputArea::Inner::keyPressEvent(QKeyEvent *e) { void InputArea::Inner::contextMenuEvent(QContextMenuEvent *e) { if (auto menu = createStandardContextMenu()) { - (new Ui::PopupMenu(menu))->popup(e->globalPos()); + (new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos()); } } @@ -3170,7 +3170,7 @@ void InputField::Inner::keyPressEvent(QKeyEvent *e) { void InputField::Inner::contextMenuEvent(QContextMenuEvent *e) { if (auto menu = createStandardContextMenu()) { - (new Ui::PopupMenu(menu))->popup(e->globalPos()); + (new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos()); } } @@ -3482,7 +3482,7 @@ void MaskedInputField::createPlaceholderPath() { void MaskedInputField::contextMenuEvent(QContextMenuEvent *e) { if (auto menu = createStandardContextMenu()) { - (new Ui::PopupMenu(menu))->popup(e->globalPos()); + (new Ui::PopupMenu(nullptr, menu))->popup(e->globalPos()); } } diff --git a/Telegram/SourceFiles/ui/widgets/labels.cpp b/Telegram/SourceFiles/ui/widgets/labels.cpp index 75a099573..02c120cd8 100644 --- a/Telegram/SourceFiles/ui/widgets/labels.cpp +++ b/Telegram/SourceFiles/ui/widgets/labels.cpp @@ -496,7 +496,7 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason) uponSelection = hasSelection; } - _contextMenu = new Ui::PopupMenu(); + _contextMenu = new Ui::PopupMenu(nullptr); _contextMenuClickHandler = ClickHandler::getActive(); diff --git a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp index 467ca31fc..95ae76912 100644 --- a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp @@ -25,13 +25,13 @@ namespace Ui { -PopupMenu::PopupMenu(const style::PopupMenu &st) : TWidget(nullptr) +PopupMenu::PopupMenu(QWidget*, const style::PopupMenu &st) : TWidget(nullptr) , _st(st) , _menu(this, _st.menu) { init(); } -PopupMenu::PopupMenu(QMenu *menu, const style::PopupMenu &st) : TWidget(nullptr) +PopupMenu::PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st) : TWidget(nullptr) , _st(st) , _menu(this, menu, _st.menu) { init(); @@ -478,6 +478,9 @@ PopupMenu::~PopupMenu() { w->reActivateWindow(); } #endif + if (_destroyedCallback) { + _destroyedCallback(); + } } } // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/popup_menu.h b/Telegram/SourceFiles/ui/widgets/popup_menu.h index 86271dfaa..3222a30c9 100644 --- a/Telegram/SourceFiles/ui/widgets/popup_menu.h +++ b/Telegram/SourceFiles/ui/widgets/popup_menu.h @@ -25,8 +25,8 @@ namespace Ui { class PopupMenu : public TWidget { public: - PopupMenu(const style::PopupMenu &st = st::defaultPopupMenu); - PopupMenu(QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu); + PopupMenu(QWidget*, const style::PopupMenu &st = st::defaultPopupMenu); + PopupMenu(QWidget*, QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu); QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); QAction *addAction(const QString &text, base::lambda &&callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); @@ -40,6 +40,10 @@ public: void popup(const QPoint &p); void hideMenu(bool fast = false); + void setDestroyedCallback(base::lambda &&callback) { + _destroyedCallback = std_::move(callback); + } + ~PopupMenu(); protected: @@ -130,6 +134,8 @@ private: bool _triggering = false; bool _deleteLater = false; + base::lambda _destroyedCallback; + }; } // namespace Ui diff --git a/Telegram/build/version b/Telegram/build/version index 0c21443fd..d92344102 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10026 +AppVersion 10027 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.26 -AppVersionStr 0.10.26 +AppVersionStrSmall 0.10.27 +AppVersionStr 0.10.27 AlphaChannel 1 BetaVersion 0