2014-05-30 12:53:19 +04:00
/*
This file is part of Telegram Desktop ,
2014-12-01 13:47:38 +03:00
the official desktop version of Telegram messaging app , see https : //telegram.org
2014-05-30 12:53:19 +04:00
Telegram Desktop is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
It is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2015-10-03 16:16:42 +03:00
In addition , as a special exception , the copyright holders give permission
to link the code of portions of this program with the OpenSSL library .
2014-05-30 12:53:19 +04:00
Full license : https : //github.com/telegramdesktop/tdesktop/blob/master/LICENSE
2015-10-03 16:16:42 +03:00
Copyright ( c ) 2014 - 2015 John Preston , https : //desktop.telegram.org
2014-05-30 12:53:19 +04:00
*/
# include "stdafx.h"
# include "lang.h"
# include "addcontactbox.h"
# include "contactsbox.h"
# include "mainwidget.h"
# include "window.h"
2015-09-16 16:04:08 +03:00
# include "application.h"
# include "gui/filedialog.h"
# include "photocropbox.h"
2015-06-15 20:19:24 +03:00
# include "confirmbox.h"
2015-10-11 10:37:24 +02:00
ContactsInner : : ContactsInner ( CreatingGroupType creating ) : TWidget ( )
, _rowHeight ( st : : contactsPadding . top ( ) + st : : contactsPhotoSize + st : : contactsPadding . bottom ( ) )
, _newItemHeight ( creating = = CreatingGroupNone ? st : : contactsNewItemHeight : 0 )
, _newItemSel ( false )
, _chat ( 0 )
, _channel ( 0 )
, _channelFilter ( MembersFilterRecent )
, _bot ( 0 )
, _creating ( creating )
, _addToChat ( 0 )
, _addAdmin ( 0 )
, _addAdminRequestId ( 0 )
, _addAdminBox ( 0 )
, _contacts ( & App : : main ( ) - > contactsList ( ) )
, _sel ( 0 )
, _filteredSel ( - 1 )
, _mouseSel ( false )
, _selCount ( 0 )
, _searching ( false )
, _byUsernameSel ( - 1 )
, _addContactLnk ( this , lang ( lng_add_contact_button ) ) {
2015-04-02 13:33:19 +03:00
init ( ) ;
}
2014-11-25 15:15:29 +03:00
2015-10-11 10:37:24 +02:00
ContactsInner : : ContactsInner ( ChannelData * channel , MembersFilter channelFilter , const MembersAlreadyIn & already ) : TWidget ( )
, _rowHeight ( st : : contactsPadding . top ( ) + st : : contactsPhotoSize + st : : contactsPadding . bottom ( ) )
, _newItemHeight ( 0 )
, _newItemSel ( false )
, _chat ( 0 )
, _channel ( channel )
, _channelFilter ( channelFilter )
, _bot ( 0 )
, _creating ( CreatingGroupChannel )
, _already ( already )
, _addToChat ( 0 )
, _addAdmin ( 0 )
, _addAdminRequestId ( 0 )
, _addAdminBox ( 0 )
, _contacts ( & App : : main ( ) - > contactsList ( ) )
, _sel ( 0 )
, _filteredSel ( - 1 )
, _mouseSel ( false )
, _selCount ( 0 )
, _searching ( false )
, _byUsernameSel ( - 1 )
, _addContactLnk ( this , lang ( lng_add_contact_button ) ) {
2015-09-16 16:04:08 +03:00
init ( ) ;
}
2015-10-11 10:37:24 +02:00
ContactsInner : : ContactsInner ( ChatData * chat ) : TWidget ( )
, _rowHeight ( st : : contactsPadding . top ( ) + st : : contactsPhotoSize + st : : contactsPadding . bottom ( ) )
, _newItemHeight ( 0 )
, _newItemSel ( false )
, _chat ( chat )
, _channel ( 0 )
, _channelFilter ( MembersFilterRecent )
, _bot ( 0 )
, _creating ( CreatingGroupNone )
, _addToChat ( 0 )
, _addAdmin ( 0 )
, _addAdminRequestId ( 0 )
, _addAdminBox ( 0 )
, _contacts ( & App : : main ( ) - > contactsList ( ) )
, _sel ( 0 )
, _filteredSel ( - 1 )
, _mouseSel ( false )
, _selCount ( 0 )
, _searching ( false )
, _byUsernameSel ( - 1 )
, _addContactLnk ( this , lang ( lng_add_contact_button ) ) {
2015-04-02 13:33:19 +03:00
init ( ) ;
}
2015-10-11 10:37:24 +02:00
ContactsInner : : ContactsInner ( UserData * bot ) : TWidget ( )
, _rowHeight ( st : : contactsPadding . top ( ) + st : : contactsPhotoSize + st : : contactsPadding . bottom ( ) )
, _newItemHeight ( 0 )
, _newItemSel ( false )
, _chat ( 0 )
, _channel ( 0 )
, _channelFilter ( MembersFilterRecent )
, _bot ( bot )
, _creating ( CreatingGroupNone )
, _addToChat ( 0 )
, _addAdmin ( 0 )
, _addAdminRequestId ( 0 )
, _addAdminBox ( 0 )
, _contacts ( new DialogsIndexed ( DialogsSortByAdd ) )
, _sel ( 0 )
, _filteredSel ( - 1 )
, _mouseSel ( false )
, _selCount ( 0 )
, _searching ( false )
, _byUsernameSel ( - 1 )
, _addContactLnk ( this , lang ( lng_add_contact_button ) ) {
2015-06-15 20:19:24 +03:00
DialogsIndexed & v ( App : : main ( ) - > dialogsList ( ) ) ;
for ( DialogRow * r = v . list . begin ; r ! = v . list . end ; r = r - > next ) {
2015-09-21 23:57:42 +03:00
if ( r - > history - > peer - > isChat ( ) & & ! r - > history - > peer - > asChat ( ) - > isForbidden & & ! r - > history - > peer - > asChat ( ) - > haveLeft ) {
2015-06-15 20:19:24 +03:00
_contacts - > addToEnd ( r - > history ) ;
}
}
init ( ) ;
}
2015-04-02 13:33:19 +03:00
void ContactsInner : : init ( ) {
2015-10-11 10:37:24 +02:00
connect ( App : : wnd ( ) , SIGNAL ( imageLoaded ( ) ) , this , SLOT ( update ( ) ) ) ;
2014-11-25 15:15:29 +03:00
connect ( & _addContactLnk , SIGNAL ( clicked ( ) ) , App : : wnd ( ) , SLOT ( onShowAddContact ( ) ) ) ;
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
setAttribute ( Qt : : WA_OpaquePaintEvent ) ;
2014-05-30 12:53:19 +04:00
for ( DialogRow * r = _contacts - > list . begin ; r ! = _contacts - > list . end ; r = r - > next ) {
r - > attached = 0 ;
}
2014-11-25 15:15:29 +03:00
_filter = qsl ( " a " ) ;
updateFilter ( ) ;
2015-09-21 23:57:42 +03:00
connect ( App : : main ( ) , SIGNAL ( dialogRowReplaced ( DialogRow * , DialogRow * ) ) , this , SLOT ( onDialogRowReplaced ( DialogRow * , DialogRow * ) ) ) ;
2014-05-30 12:53:19 +04:00
connect ( App : : main ( ) , SIGNAL ( peerUpdated ( PeerData * ) ) , this , SLOT ( peerUpdated ( PeerData * ) ) ) ;
2015-09-21 23:57:42 +03:00
connect ( App : : main ( ) , SIGNAL ( peerNameChanged ( PeerData * , const PeerData : : Names & , const PeerData : : NameFirstChars & ) ) , this , SLOT ( onPeerNameChanged ( PeerData * , const PeerData : : Names & , const PeerData : : NameFirstChars & ) ) ) ;
connect ( App : : main ( ) , SIGNAL ( peerPhotoChanged ( PeerData * ) ) , this , SLOT ( peerUpdated ( PeerData * ) ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-06-15 20:19:24 +03:00
void ContactsInner : : onPeerNameChanged ( PeerData * peer , const PeerData : : Names & oldNames , const PeerData : : NameFirstChars & oldChars ) {
if ( bot ( ) ) {
_contacts - > peerNameChanged ( peer , oldNames , oldChars ) ;
}
peerUpdated ( peer ) ;
}
void ContactsInner : : onAddBot ( ) {
2015-06-17 22:43:03 +03:00
if ( _bot - > botInfo & & ! _bot - > botInfo - > startGroupToken . isEmpty ( ) ) {
2015-09-16 16:04:08 +03:00
MTP : : send ( MTPmessages_StartBot ( _bot - > inputUser , _addToChat - > inputChat , MTP_long ( MTP : : nonce < uint64 > ( ) ) , MTP_string ( _bot - > botInfo - > startGroupToken ) ) , App : : main ( ) - > rpcDone ( & MainWidget : : sentUpdatesReceived ) , App : : main ( ) - > rpcFail ( & MainWidget : : addParticipantFail , _bot ) ) ;
2015-06-17 22:43:03 +03:00
} else {
App : : main ( ) - > addParticipants ( _addToChat , QVector < UserData * > ( 1 , _bot ) ) ;
}
2015-09-16 16:04:08 +03:00
App : : wnd ( ) - > hideLayer ( ) ;
App : : main ( ) - > showPeerHistory ( _addToChat - > id , ShowAtUnreadMsgId ) ;
2015-06-15 20:19:24 +03:00
}
2015-09-23 20:43:08 +03:00
void ContactsInner : : onAddAdmin ( ) {
if ( _addAdminRequestId ) return ;
_addAdminRequestId = MTP : : send ( MTPchannels_EditAdmin ( _channel - > inputChannel , _addAdmin - > inputUser , MTP_channelRoleEditor ( ) ) , rpcDone ( & ContactsInner : : addAdminDone ) , rpcFail ( & ContactsInner : : addAdminFail ) ) ;
}
void ContactsInner : : onNoAddAdminBox ( QObject * obj ) {
if ( obj = = _addAdminBox ) {
_addAdminBox = 0 ;
}
}
void ContactsInner : : addAdminDone ( const MTPBool & result , mtpRequestId req ) {
if ( req ! = _addAdminRequestId ) return ;
_addAdminRequestId = 0 ;
if ( _addAdminBox ) _addAdminBox - > onClose ( ) ;
emit adminAdded ( ) ;
}
bool ContactsInner : : addAdminFail ( const RPCError & error , mtpRequestId req ) {
if ( mtpIsFlood ( error ) ) return false ;
if ( req ! = _addAdminRequestId ) return true ;
_addAdminRequestId = 0 ;
2015-10-01 17:05:05 +03:00
if ( error . type ( ) = = " USERS_TOO_MUCH " ) {
App : : wnd ( ) - > replaceLayer ( new MaxInviteBox ( _channel - > invitationUrl ) ) ;
} else {
if ( _addAdminBox ) _addAdminBox - > onClose ( ) ;
emit adminAdded ( ) ;
}
2015-09-23 20:43:08 +03:00
return true ;
}
2014-05-30 12:53:19 +04:00
void ContactsInner : : peerUpdated ( PeerData * peer ) {
2015-04-02 13:33:19 +03:00
if ( _chat & & ( ! peer | | peer = = _chat ) ) {
2015-09-21 23:57:42 +03:00
if ( _chat - > isForbidden | | _chat - > haveLeft ) {
2015-04-02 13:33:19 +03:00
App : : wnd ( ) - > hideLayer ( ) ;
} else if ( ! _chat - > participants . isEmpty ( ) | | _chat - > count < = 0 ) {
for ( ContactsData : : iterator i = _contactsData . begin ( ) , e = _contactsData . end ( ) ; i ! = e ; + + i ) {
delete i . value ( ) ;
}
_contactsData . clear ( ) ;
for ( DialogRow * row = _contacts - > list . begin ; row - > next ; row = row - > next ) {
row - > attached = 0 ;
}
if ( ! _filter . isEmpty ( ) ) {
for ( int32 j = 0 , s = _filtered . size ( ) ; j < s ; + + j ) {
_filtered [ j ] - > attached = 0 ;
}
}
}
2015-10-01 17:05:05 +03:00
update ( ) ;
2015-06-15 20:19:24 +03:00
} else {
ContactsData : : iterator i = _contactsData . find ( peer ) ;
2014-05-30 12:53:19 +04:00
if ( i ! = _contactsData . cend ( ) ) {
for ( DialogRow * row = _contacts - > list . begin ; row - > next ; row = row - > next ) {
2015-10-01 17:05:05 +03:00
if ( row - > attached = = i . value ( ) ) {
row - > attached = 0 ;
2015-10-11 10:37:24 +02:00
update ( 0 , _newItemHeight + _rowHeight * row - > pos , width ( ) , _rowHeight ) ;
2015-10-01 17:05:05 +03:00
}
2014-05-30 12:53:19 +04:00
}
if ( ! _filter . isEmpty ( ) ) {
for ( int32 j = 0 , s = _filtered . size ( ) ; j < s ; + + j ) {
2015-10-01 17:05:05 +03:00
if ( _filtered [ j ] - > attached = = i . value ( ) ) {
_filtered [ j ] - > attached = 0 ;
2015-10-11 10:37:24 +02:00
update ( 0 , _rowHeight * j , width ( ) , _rowHeight ) ;
2015-10-01 17:05:05 +03:00
}
2014-05-30 12:53:19 +04:00
}
}
delete i . value ( ) ;
_contactsData . erase ( i ) ;
}
}
}
void ContactsInner : : loadProfilePhotos ( int32 yFrom ) {
int32 yTo = yFrom + ( parentWidget ( ) ? parentWidget ( ) - > height ( ) : App : : wnd ( ) - > height ( ) ) * 5 ;
MTP : : clearLoaderPriorities ( ) ;
if ( yTo < 0 ) return ;
if ( yFrom < 0 ) yFrom = 0 ;
if ( _filter . isEmpty ( ) ) {
if ( _contacts - > list . count ) {
2015-10-11 10:37:24 +02:00
_contacts - > list . adjustCurrent ( yFrom - _newItemHeight , _rowHeight ) ;
2014-05-30 12:53:19 +04:00
for (
DialogRow * preloadFrom = _contacts - > list . current ;
2015-10-11 10:37:24 +02:00
preloadFrom ! = _contacts - > list . end & & ( _newItemHeight + preloadFrom - > pos * _rowHeight ) < yTo ;
2014-05-30 12:53:19 +04:00
preloadFrom = preloadFrom - > next
) {
preloadFrom - > history - > peer - > photo - > load ( ) ;
}
}
} else if ( ! _filtered . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
int32 from = yFrom / _rowHeight ;
2014-05-30 12:53:19 +04:00
if ( from < 0 ) from = 0 ;
if ( from < _filtered . size ( ) ) {
2015-10-11 10:37:24 +02:00
int32 to = ( yTo / _rowHeight ) + 1 ;
2014-05-30 12:53:19 +04:00
if ( to > _filtered . size ( ) ) to = _filtered . size ( ) ;
for ( ; from < to ; + + from ) {
_filtered [ from ] - > history - > peer - > photo - > load ( ) ;
}
}
}
}
ContactsInner : : ContactData * ContactsInner : : contactData ( DialogRow * row ) {
ContactData * data = ( ContactData * ) row - > attached ;
if ( ! data ) {
2015-06-15 20:19:24 +03:00
PeerData * peer = row - > history - > peer ;
ContactsData : : const_iterator i = _contactsData . constFind ( peer ) ;
2014-05-30 12:53:19 +04:00
if ( i = = _contactsData . cend ( ) ) {
2015-06-15 20:19:24 +03:00
_contactsData . insert ( peer , data = new ContactData ( ) ) ;
2015-09-22 12:58:40 +03:00
if ( peer - > isUser ( ) ) {
if ( _chat ) {
data - > inchat = _chat - > participants . contains ( peer - > asUser ( ) ) ;
2015-09-23 20:43:08 +03:00
} else if ( _creating = = CreatingGroupGroup ) {
2015-09-22 12:58:40 +03:00
data - > inchat = ( peerToUser ( peer - > id ) = = MTP : : authedId ( ) ) ;
2015-09-23 20:43:08 +03:00
} else if ( _channel ) {
data - > inchat = ( peerToUser ( peer - > id ) = = MTP : : authedId ( ) ) | | _already . contains ( peer - > asUser ( ) ) ;
2015-09-22 12:58:40 +03:00
} else {
data - > inchat = false ;
}
} else {
data - > inchat = false ;
}
2015-08-07 15:11:50 +03:00
data - > check = _checkedContacts . contains ( peer ) ;
2015-10-11 10:37:24 +02:00
data - > name . setText ( st : : contactsNameFont , peer - > name , _textNameOptions ) ;
2015-09-03 13:48:40 +03:00
if ( peer - > isUser ( ) ) {
data - > online = App : : onlineText ( peer - > asUser ( ) , _time ) ;
} else if ( peer - > isChat ( ) ) {
2015-06-15 20:19:24 +03:00
ChatData * chat = peer - > asChat ( ) ;
2015-09-21 23:57:42 +03:00
if ( chat - > isForbidden | | chat - > haveLeft ) {
2015-06-15 20:19:24 +03:00
data - > online = lang ( lng_chat_status_unaccessible ) ;
} else {
data - > online = lng_chat_status_members ( lt_count , chat - > count ) ;
}
2015-09-03 13:48:40 +03:00
} else if ( peer - > isChannel ( ) ) {
2015-09-19 12:13:21 +03:00
data - > online = lang ( lng_channel_status ) ;
2015-06-15 20:19:24 +03:00
}
2014-05-30 12:53:19 +04:00
} else {
data = i . value ( ) ;
}
row - > attached = data ;
}
return data ;
}
2015-09-23 20:43:08 +03:00
void ContactsInner : : paintDialog ( Painter & p , PeerData * peer , ContactData * data , bool sel ) {
2015-09-03 13:48:40 +03:00
UserData * user = peer - > asUser ( ) ;
2015-06-15 20:19:24 +03:00
2015-09-16 16:04:08 +03:00
if ( data - > inchat | | data - > check | | selectedCount ( ) > = cMaxGroupCount ( ) ) {
2015-04-02 13:33:19 +03:00
sel = false ;
}
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
p . fillRect ( 0 , 0 , width ( ) , _rowHeight , ( ( data - > inchat | | data - > check ) ? st : : contactsBgActive : ( sel ? st : : contactsBgOver : st : : white ) ) - > b ) ;
p . drawPixmapLeft ( st : : contactsPadding . left ( ) , st : : contactsPadding . top ( ) , width ( ) , peer - > photo - > pix ( st : : contactsPhotoSize ) ) ;
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
p . setPen ( ( data - > inchat | | data - > check ) ? st : : white : st : : black ) ;
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
int32 namex = st : : contactsPadding . left ( ) + st : : contactsPhotoSize + st : : contactsPadding . left ( ) ;
int32 iconw = ( _chat | | _creating ! = CreatingGroupNone ) ? ( st : : contactsCheckPosition . x ( ) * 2 + st : : contactsCheckIcon . pxWidth ( ) ) : 0 ;
int32 namew = width ( ) - namex - st : : contactsPadding . right ( ) - iconw ;
2015-09-23 20:43:08 +03:00
if ( peer - > isChannel ( ) & & peer - > asChannel ( ) - > isVerified ( ) ) {
namew - = st : : verifiedCheck . pxWidth ( ) + st : : verifiedCheckPos . x ( ) ;
2015-10-11 10:37:24 +02:00
p . drawSpriteLeft ( namex + qMin ( data - > name . maxWidth ( ) , namew ) + st : : verifiedCheckPos . x ( ) , st : : contactsPadding . top ( ) + st : : contactsNameTop + st : : verifiedCheckPos . y ( ) , width ( ) , st : : verifiedCheck ) ;
2015-09-23 20:43:08 +03:00
}
2015-10-11 10:37:24 +02:00
data - > name . drawElided ( p , namex , st : : contactsPadding . top ( ) + st : : contactsNameTop , namew ) ;
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
if ( _chat | | ( _creating ! = CreatingGroupNone & & ( ! _channel | | _channelFilter ! = MembersFilterAdmins ) ) ) {
2015-04-02 13:33:19 +03:00
if ( sel | | data - > check ) {
2015-10-11 10:37:24 +02:00
p . drawSpriteRight ( st : : contactsPadding . right ( ) + st : : contactsCheckPosition . x ( ) , st : : contactsPadding . top ( ) + st : : contactsCheckPosition . y ( ) , width ( ) , ( data - > check ? st : : contactsCheckActiveIcon : st : : contactsCheckIcon ) ) ;
2015-04-02 13:33:19 +03:00
}
2014-05-30 12:53:19 +04:00
}
2015-09-06 13:17:09 +03:00
bool uname = ( user | | peer - > isChannel ( ) ) & & ( data - > online . at ( 0 ) = = ' @ ' ) ;
2015-10-11 10:37:24 +02:00
p . setFont ( st : : contactsStatusFont - > f ) ;
2015-09-06 13:17:09 +03:00
if ( uname & & ! data - > inchat & & ! data - > check & & ! _lastQuery . isEmpty ( ) & & peer - > userName ( ) . startsWith ( _lastQuery , Qt : : CaseInsensitive ) ) {
2015-10-11 10:37:24 +02:00
int32 availw = width ( ) - namex - st : : contactsPadding . right ( ) - iconw ;
2015-09-06 13:17:09 +03:00
QString first = ' @ ' + peer - > userName ( ) . mid ( 0 , _lastQuery . size ( ) ) , second = peer - > userName ( ) . mid ( _lastQuery . size ( ) ) ;
2015-10-11 10:37:24 +02:00
int32 w = st : : contactsStatusFont - > width ( first ) ;
2015-04-02 13:33:19 +03:00
if ( w > = availw | | second . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
p . setPen ( st : : contactsStatusFgOnline ) ;
p . drawTextLeft ( namex , st : : contactsPadding . top ( ) + st : : contactsStatusTop , width ( ) , st : : contactsStatusFont - > elided ( first , availw ) ) ;
2015-04-02 13:33:19 +03:00
} else {
2015-10-11 10:37:24 +02:00
second = st : : contactsStatusFont - > elided ( second , availw - w ) ;
int32 secondw = st : : contactsStatusFont - > width ( second ) ;
p . setPen ( st : : contactsStatusFgOnline ) ;
p . drawTextLeft ( namex , st : : contactsPadding . top ( ) + st : : contactsStatusTop , width ( ) - secondw , first ) ;
p . setPen ( sel ? st : : contactsStatusFgOver : st : : contactsStatusFg ) ;
p . drawTextLeft ( namex + w , st : : contactsPadding . top ( ) + st : : contactsStatusTop , width ( ) + w , second ) ;
2015-04-02 13:33:19 +03:00
}
} else {
if ( data - > inchat | | data - > check ) {
2015-10-11 10:37:24 +02:00
p . setPen ( st : : white ) ;
2015-09-06 13:17:09 +03:00
} else if ( ( user & & ( uname | | App : : onlineColorUse ( user , _time ) ) ) | | ( peer - > isChannel ( ) & & uname ) ) {
2015-10-11 10:37:24 +02:00
p . setPen ( st : : contactsStatusFgOnline ) ;
2015-04-02 13:33:19 +03:00
} else {
2015-10-11 10:37:24 +02:00
p . setPen ( sel ? st : : contactsStatusFgOver : st : : contactsStatusFg ) ;
2015-04-02 13:33:19 +03:00
}
2015-10-11 10:37:24 +02:00
p . drawTextLeft ( namex , st : : contactsPadding . top ( ) + st : : contactsStatusTop , width ( ) , data - > online ) ;
2015-04-02 13:33:19 +03:00
}
2014-05-30 12:53:19 +04:00
}
void ContactsInner : : paintEvent ( QPaintEvent * e ) {
QRect r ( e - > rect ( ) ) ;
2015-09-23 20:43:08 +03:00
Painter p ( this ) ;
2014-05-30 12:53:19 +04:00
2015-10-01 17:05:05 +03:00
p . setClipRect ( r ) ;
2014-05-30 12:53:19 +04:00
_time = unixtime ( ) ;
p . fillRect ( r , st : : white - > b ) ;
2015-10-01 17:05:05 +03:00
int32 yFrom = r . y ( ) , yTo = r . y ( ) + r . height ( ) ;
2014-05-30 12:53:19 +04:00
if ( _filter . isEmpty ( ) ) {
2015-04-02 13:33:19 +03:00
if ( _contacts - > list . count | | ! _byUsername . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
if ( _newItemHeight ) {
p . fillRect ( 0 , 0 , width ( ) , _newItemHeight , ( _newItemSel ? st : : contactsBgOver : st : : white ) - > b ) ;
p . drawSpriteLeft ( st : : contactsNewItemIconPosition . x ( ) , st : : contactsNewItemIconPosition . y ( ) , width ( ) , st : : contactsNewItemIcon ) ;
p . setFont ( st : : contactsNameFont ) ;
p . setPen ( st : : contactsNewItemFg ) ;
p . drawTextLeft ( st : : contactsPadding . left ( ) + st : : contactsPhotoSize + st : : contactsPadding . left ( ) , st : : contactsNewItemTop , width ( ) , lang ( lng_add_contact_button ) ) ;
yFrom - = _newItemHeight ;
yTo - = _newItemHeight ;
p . translate ( 0 , _newItemHeight ) ;
}
2015-04-02 13:33:19 +03:00
if ( _contacts - > list . count ) {
2015-10-11 10:37:24 +02:00
_contacts - > list . adjustCurrent ( yFrom , _rowHeight ) ;
2014-05-30 12:53:19 +04:00
2015-04-02 13:33:19 +03:00
DialogRow * drawFrom = _contacts - > list . current ;
2015-10-11 10:37:24 +02:00
p . translate ( 0 , drawFrom - > pos * _rowHeight ) ;
while ( drawFrom ! = _contacts - > list . end & & drawFrom - > pos * _rowHeight < yTo ) {
2015-06-15 20:19:24 +03:00
paintDialog ( p , drawFrom - > history - > peer , contactData ( drawFrom ) , ( drawFrom = = _sel ) ) ;
2015-10-11 10:37:24 +02:00
p . translate ( 0 , _rowHeight ) ;
2015-04-02 13:33:19 +03:00
drawFrom = drawFrom - > next ;
}
2015-10-11 10:37:24 +02:00
yFrom - = _contacts - > list . count * _rowHeight ;
yTo - = _contacts - > list . count * _rowHeight ;
2015-04-02 13:33:19 +03:00
}
if ( ! _byUsername . 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_search_global_results ) , style : : al_center ) ;
2015-10-11 10:37:24 +02:00
yFrom - = st : : searchedBarHeight ;
yTo - = st : : searchedBarHeight ;
2015-04-02 13:33:19 +03:00
p . translate ( 0 , st : : searchedBarHeight ) ;
2015-10-11 10:37:24 +02:00
int32 from = floorclamp ( yFrom , _rowHeight , 0 , _byUsername . size ( ) ) ;
int32 to = ceilclamp ( yTo , _rowHeight , 0 , _byUsername . size ( ) ) ;
p . translate ( 0 , from * _rowHeight ) ;
2015-10-01 17:05:05 +03:00
for ( ; from < to ; + + from ) {
paintDialog ( p , _byUsername [ from ] , d_byUsername [ from ] , ( _byUsernameSel = = from ) ) ;
2015-10-11 10:37:24 +02:00
p . translate ( 0 , _rowHeight ) ;
2015-04-02 13:33:19 +03:00
}
2014-05-30 12:53:19 +04:00
}
} else {
2014-11-25 15:15:29 +03:00
p . setFont ( st : : noContactsFont - > f ) ;
p . setPen ( st : : noContactsColor - > p ) ;
2015-06-15 20:19:24 +03:00
QString text ;
int32 skip = 0 ;
if ( bot ( ) ) {
text = lang ( cDialogsReceived ( ) ? lng_bot_no_groups : lng_contacts_loading ) ;
} else if ( cContactsReceived ( ) & & ! _searching ) {
text = lang ( lng_no_contacts ) ;
skip = st : : noContactsFont - > height ;
} else {
text = lang ( lng_contacts_loading ) ;
}
p . drawText ( QRect ( 0 , 0 , width ( ) , st : : noContactsHeight - skip ) , text , style : : al_center ) ;
2014-05-30 12:53:19 +04:00
}
} else {
2015-04-02 13:33:19 +03:00
if ( _filtered . isEmpty ( ) & & _byUsernameFiltered . isEmpty ( ) ) {
2014-11-25 15:15:29 +03:00
p . setFont ( st : : noContactsFont - > f ) ;
p . setPen ( st : : noContactsColor - > p ) ;
2015-06-15 20:19:24 +03:00
QString text ;
if ( bot ( ) ) {
text = lang ( cDialogsReceived ( ) ? lng_bot_groups_not_found : lng_contacts_loading ) ;
} else {
text = lang ( ( cContactsReceived ( ) & & ! _searching ) ? lng_contacts_not_found : lng_contacts_loading ) ;
}
p . drawText ( QRect ( 0 , 0 , width ( ) , st : : noContactsHeight ) , text , style : : al_center ) ;
2014-05-30 12:53:19 +04:00
} else {
2015-04-02 13:33:19 +03:00
if ( ! _filtered . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
int32 from = floorclamp ( yFrom , _rowHeight , 0 , _filtered . size ( ) ) ;
int32 to = ceilclamp ( yTo , _rowHeight , 0 , _filtered . size ( ) ) ;
p . translate ( 0 , from * _rowHeight ) ;
2015-10-01 17:05:05 +03:00
for ( ; from < to ; + + from ) {
paintDialog ( p , _filtered [ from ] - > history - > peer , contactData ( _filtered [ from ] ) , ( _filteredSel = = from ) ) ;
2015-10-11 10:37:24 +02:00
p . translate ( 0 , _rowHeight ) ;
2015-04-02 13:33:19 +03:00
}
}
if ( ! _byUsernameFiltered . 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_search_global_results ) , style : : al_center ) ;
p . translate ( 0 , st : : searchedBarHeight ) ;
2015-10-11 10:37:24 +02:00
yFrom - = _filtered . size ( ) * _rowHeight + st : : searchedBarHeight ;
yTo - = _filtered . size ( ) * _rowHeight + st : : searchedBarHeight ;
int32 from = floorclamp ( yFrom , _rowHeight , 0 , _byUsernameFiltered . size ( ) ) ;
int32 to = ceilclamp ( yTo , _rowHeight , 0 , _byUsernameFiltered . size ( ) ) ;
p . translate ( 0 , from * _rowHeight ) ;
2015-10-01 17:05:05 +03:00
for ( ; from < to ; + + from ) {
paintDialog ( p , _byUsernameFiltered [ from ] , d_byUsernameFiltered [ from ] , ( _byUsernameSel = = from ) ) ;
2015-10-11 10:37:24 +02:00
p . translate ( 0 , _rowHeight ) ;
2014-05-30 12:53:19 +04:00
}
}
}
}
}
void ContactsInner : : enterEvent ( QEvent * e ) {
setMouseTracking ( true ) ;
}
2015-10-01 17:05:05 +03:00
void ContactsInner : : updateSelectedRow ( ) {
if ( _filter . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
if ( _newItemSel ) {
update ( 0 , 0 , width ( ) , _newItemHeight ) ;
}
2015-10-01 17:05:05 +03:00
if ( _sel ) {
2015-10-11 10:37:24 +02:00
update ( 0 , _newItemHeight + _sel - > pos * _rowHeight , width ( ) , _rowHeight ) ;
2015-10-01 17:05:05 +03:00
}
if ( _byUsernameSel > = 0 ) {
2015-10-11 10:37:24 +02:00
update ( 0 , _newItemHeight + _contacts - > list . count * _rowHeight + st : : searchedBarHeight + _byUsernameSel * _rowHeight , width ( ) , _rowHeight ) ;
2015-10-01 17:05:05 +03:00
}
} else {
if ( _filteredSel > = 0 ) {
2015-10-11 10:37:24 +02:00
update ( 0 , _filteredSel * _rowHeight , width ( ) , _rowHeight ) ;
2015-10-01 17:05:05 +03:00
}
if ( _byUsernameSel > = 0 ) {
2015-10-11 10:37:24 +02:00
update ( 0 , _filtered . size ( ) * _rowHeight + st : : searchedBarHeight + _byUsernameSel * _rowHeight , width ( ) , _rowHeight ) ;
2015-10-01 17:05:05 +03:00
}
}
}
2014-05-30 12:53:19 +04:00
void ContactsInner : : leaveEvent ( QEvent * e ) {
2015-10-11 10:37:24 +02:00
_mouseSel = false ;
2014-05-30 12:53:19 +04:00
setMouseTracking ( false ) ;
2015-10-11 10:37:24 +02:00
if ( _newItemSel | | _sel | | _filteredSel > = 0 | | _byUsernameSel > = 0 ) {
2015-10-01 17:05:05 +03:00
updateSelectedRow ( ) ;
2015-04-02 13:33:19 +03:00
_sel = 0 ;
2015-10-11 10:37:24 +02:00
_newItemSel = false ;
2015-04-02 13:33:19 +03:00
_filteredSel = _byUsernameSel = - 1 ;
}
2014-05-30 12:53:19 +04:00
}
void ContactsInner : : mouseMoveEvent ( QMouseEvent * e ) {
_mouseSel = true ;
_lastMousePos = e - > globalPos ( ) ;
updateSel ( ) ;
}
void ContactsInner : : mousePressEvent ( QMouseEvent * e ) {
_mouseSel = true ;
_lastMousePos = e - > globalPos ( ) ;
updateSel ( ) ;
if ( e - > button ( ) = = Qt : : LeftButton ) {
chooseParticipant ( ) ;
}
}
void ContactsInner : : chooseParticipant ( ) {
2015-09-23 20:43:08 +03:00
bool addingAdmin = ( _channel & & _channelFilter = = MembersFilterAdmins ) ;
if ( ! addingAdmin & & ( _chat | | _creating ! = CreatingGroupNone ) ) {
2015-04-02 13:33:19 +03:00
_time = unixtime ( ) ;
if ( _filter . isEmpty ( ) ) {
if ( _byUsernameSel > = 0 & & _byUsernameSel < _byUsername . size ( ) ) {
if ( d_byUsername [ _byUsernameSel ] - > inchat ) return ;
2015-08-07 15:11:50 +03:00
changeCheckState ( d_byUsername [ _byUsernameSel ] , _byUsername [ _byUsernameSel ] ) ;
2015-04-02 13:33:19 +03:00
} else {
if ( ! _sel | | contactData ( _sel ) - > inchat ) return ;
changeCheckState ( _sel ) ;
}
} else {
if ( _byUsernameSel > = 0 & & _byUsernameSel < _byUsernameFiltered . size ( ) ) {
if ( d_byUsernameFiltered [ _byUsernameSel ] - > inchat ) return ;
2015-08-07 15:11:50 +03:00
changeCheckState ( d_byUsernameFiltered [ _byUsernameSel ] , _byUsernameFiltered [ _byUsernameSel ] ) ;
2015-04-02 13:33:19 +03:00
ContactData * moving = d_byUsernameFiltered [ _byUsernameSel ] ;
int32 i = 0 , l = d_byUsername . size ( ) ;
for ( ; i < l ; + + i ) {
if ( d_byUsername [ i ] = = moving ) {
break ;
}
}
if ( i = = l ) {
d_byUsername . push_back ( moving ) ;
_byUsername . push_back ( _byUsernameFiltered [ _byUsernameSel ] ) ;
for ( i = 0 , l = _byUsernameDatas . size ( ) ; i < l ; ) {
if ( _byUsernameDatas [ i ] = = moving ) {
_byUsernameDatas . removeAt ( i ) ;
- - l ;
} else {
+ + i ;
}
}
}
} else {
if ( _filteredSel < 0 | | _filteredSel > = _filtered . size ( ) | | contactData ( _filtered [ _filteredSel ] ) - > inchat ) return ;
changeCheckState ( _filtered [ _filteredSel ] ) ;
}
emit selectAllQuery ( ) ;
}
2014-05-30 12:53:19 +04:00
} else {
2015-06-15 20:19:24 +03:00
PeerData * peer = 0 ;
2015-04-02 13:33:19 +03:00
if ( _filter . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
if ( _newItemSel ) {
emit addRequested ( ) ;
return ;
}
2015-04-02 13:33:19 +03:00
if ( _byUsernameSel > = 0 & & _byUsernameSel < _byUsername . size ( ) ) {
2015-06-15 20:19:24 +03:00
peer = _byUsername [ _byUsernameSel ] ;
} else if ( _sel ) {
peer = _sel - > history - > peer ;
2015-04-02 13:33:19 +03:00
}
} else {
if ( _byUsernameSel > = 0 & & _byUsernameSel < _byUsernameFiltered . size ( ) ) {
2015-06-15 20:19:24 +03:00
peer = _byUsernameFiltered [ _byUsernameSel ] ;
2015-04-02 13:33:19 +03:00
} else {
if ( _filteredSel < 0 | | _filteredSel > = _filtered . size ( ) ) return ;
2015-06-15 20:19:24 +03:00
peer = _filtered [ _filteredSel ] - > history - > peer ;
2015-04-02 13:33:19 +03:00
}
}
if ( peer ) {
2015-09-23 20:43:08 +03:00
if ( addingAdmin ) {
_addAdmin = peer - > asUser ( ) ;
if ( _addAdminRequestId ) {
MTP : : cancel ( _addAdminRequestId ) ;
_addAdminRequestId = 0 ;
}
if ( _addAdminBox ) _addAdminBox - > deleteLater ( ) ;
_addAdminBox = new ConfirmBox ( lng_channel_admin_sure ( lt_user , _addAdmin - > firstName ) ) ;
connect ( _addAdminBox , SIGNAL ( confirmed ( ) ) , this , SLOT ( onAddAdmin ( ) ) ) ;
connect ( _addAdminBox , SIGNAL ( destroyed ( QObject * ) ) , this , SLOT ( onNoAddAdminBox ( QObject * ) ) ) ;
App : : wnd ( ) - > replaceLayer ( _addAdminBox ) ;
} else if ( bot ( ) & & peer - > isChat ( ) ) {
2015-06-15 20:19:24 +03:00
_addToChat = peer - > asChat ( ) ;
ConfirmBox * box = new ConfirmBox ( lng_bot_sure_invite ( lt_group , peer - > name ) ) ;
connect ( box , SIGNAL ( confirmed ( ) ) , this , SLOT ( onAddBot ( ) ) ) ;
App : : wnd ( ) - > replaceLayer ( box ) ;
} else {
App : : wnd ( ) - > hideSettings ( true ) ;
2015-07-17 22:17:37 +03:00
App : : main ( ) - > choosePeer ( peer - > id , ShowAtUnreadMsgId ) ;
2015-06-15 20:19:24 +03:00
App : : wnd ( ) - > hideLayer ( ) ;
}
2015-04-02 13:33:19 +03:00
}
2014-05-30 12:53:19 +04:00
}
2015-10-01 17:05:05 +03:00
update ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-04-02 13:33:19 +03:00
void ContactsInner : : changeCheckState ( DialogRow * row ) {
2015-08-07 15:11:50 +03:00
changeCheckState ( contactData ( row ) , row - > history - > peer ) ;
2015-04-02 13:33:19 +03:00
}
2014-05-30 12:53:19 +04:00
2015-08-07 15:11:50 +03:00
void ContactsInner : : changeCheckState ( ContactData * data , PeerData * peer ) {
2015-09-16 16:04:08 +03:00
int32 cnt = _selCount ;
2015-04-02 13:33:19 +03:00
if ( data - > check ) {
data - > check = false ;
2015-08-07 15:11:50 +03:00
_checkedContacts . remove ( peer ) ;
2015-04-02 13:33:19 +03:00
- - _selCount ;
2015-09-16 16:04:08 +03:00
} else if ( selectedCount ( ) < cMaxGroupCount ( ) ) {
2015-04-02 13:33:19 +03:00
data - > check = true ;
2015-08-07 15:11:50 +03:00
_checkedContacts . insert ( peer , true ) ;
2015-04-02 13:33:19 +03:00
+ + _selCount ;
}
2015-09-16 16:04:08 +03:00
if ( cnt ! = _selCount ) emit chosenChanged ( ) ;
}
int32 ContactsInner : : selectedCount ( ) const {
2015-09-22 12:58:40 +03:00
int32 result = _selCount ;
if ( _chat ) {
result + = ( _chat - > count > 0 ) ? _chat - > count : 1 ;
} else if ( _channel ) {
2015-09-23 20:43:08 +03:00
result + = _already . size ( ) ;
2015-09-22 12:58:40 +03:00
} else if ( _creating = = CreatingGroupGroup ) {
result + = 1 ;
}
return result ;
2015-04-02 13:33:19 +03:00
}
void ContactsInner : : updateSel ( ) {
2015-10-11 10:37:24 +02:00
if ( ! _mouseSel ) return ;
2014-05-30 12:53:19 +04:00
QPoint p ( mapFromGlobal ( _lastMousePos ) ) ;
2015-04-02 13:33:19 +03:00
bool in = parentWidget ( ) - > rect ( ) . contains ( parentWidget ( ) - > mapFromGlobal ( _lastMousePos ) ) ;
2014-05-30 12:53:19 +04:00
if ( _filter . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
bool newItemSel = false ;
if ( _newItemHeight ) {
if ( in & & ( p . y ( ) > = 0 ) & & ( p . y ( ) < _newItemHeight ) ) {
newItemSel = true ;
}
p . setY ( p . y ( ) - _newItemHeight ) ;
}
DialogRow * newSel = ( in & & ! newItemSel & & ( p . y ( ) > = 0 ) & & ( p . y ( ) < _contacts - > list . count * _rowHeight ) ) ? _contacts - > list . rowAtY ( p . y ( ) , _rowHeight ) : 0 ;
int32 byUsernameSel = ( in & & ! newItemSel & & p . y ( ) > = _contacts - > list . count * _rowHeight + st : : searchedBarHeight ) ? ( ( p . y ( ) - _contacts - > list . count * _rowHeight - st : : searchedBarHeight ) / _rowHeight ) : - 1 ;
2015-04-02 13:33:19 +03:00
if ( byUsernameSel > = _byUsername . size ( ) ) byUsernameSel = - 1 ;
2015-10-11 10:37:24 +02:00
if ( newSel ! = _sel | | byUsernameSel ! = _byUsernameSel | | newItemSel ! = _newItemSel ) {
2015-10-01 17:05:05 +03:00
updateSelectedRow ( ) ;
2015-10-11 10:37:24 +02:00
_newItemSel = newItemSel ;
2014-05-30 12:53:19 +04:00
_sel = newSel ;
2015-04-02 13:33:19 +03:00
_byUsernameSel = byUsernameSel ;
2015-10-01 17:05:05 +03:00
updateSelectedRow ( ) ;
2015-04-02 13:33:19 +03:00
}
2014-05-30 12:53:19 +04:00
} else {
2015-10-11 10:37:24 +02:00
int32 newFilteredSel = ( in & & p . y ( ) > = 0 & & p . y ( ) < _filtered . size ( ) * _rowHeight ) ? ( p . y ( ) / _rowHeight ) : - 1 ;
int32 byUsernameSel = ( in & & p . y ( ) > = _filtered . size ( ) * _rowHeight + st : : searchedBarHeight ) ? ( ( p . y ( ) - _filtered . size ( ) * _rowHeight - st : : searchedBarHeight ) / _rowHeight ) : - 1 ;
2015-04-02 13:33:19 +03:00
if ( byUsernameSel > = _byUsernameFiltered . size ( ) ) byUsernameSel = - 1 ;
if ( newFilteredSel ! = _filteredSel | | byUsernameSel ! = _byUsernameSel ) {
2015-10-01 17:05:05 +03:00
updateSelectedRow ( ) ;
2014-05-30 12:53:19 +04:00
_filteredSel = newFilteredSel ;
2015-04-02 13:33:19 +03:00
_byUsernameSel = byUsernameSel ;
2015-10-01 17:05:05 +03:00
updateSelectedRow ( ) ;
2014-05-30 12:53:19 +04:00
}
}
}
void ContactsInner : : updateFilter ( QString filter ) {
2015-04-02 13:33:19 +03:00
_lastQuery = filter . toLower ( ) . trimmed ( ) ;
2014-12-06 14:21:19 +03:00
filter = textSearchKey ( filter ) ;
2015-04-02 13:33:19 +03:00
_time = unixtime ( ) ;
2014-05-30 12:53:19 +04:00
QStringList f ;
if ( ! filter . isEmpty ( ) ) {
QStringList filterList = filter . split ( cWordSplit ( ) , QString : : SkipEmptyParts ) ;
int l = filterList . size ( ) ;
f . reserve ( l ) ;
for ( int i = 0 ; i < l ; + + i ) {
QString filterName = filterList [ i ] . trimmed ( ) ;
if ( filterName . isEmpty ( ) ) continue ;
f . push_back ( filterName ) ;
}
filter = f . join ( ' ' ) ;
}
if ( _filter ! = filter ) {
_filter = filter ;
2015-04-02 13:33:19 +03:00
_byUsernameFiltered . clear ( ) ;
d_byUsernameFiltered . clear ( ) ;
for ( int i = 0 , l = _byUsernameDatas . size ( ) ; i < l ; + + i ) {
delete _byUsernameDatas [ i ] ;
}
_byUsernameDatas . clear ( ) ;
2014-05-30 12:53:19 +04:00
if ( _filter . isEmpty ( ) ) {
2015-04-02 13:33:19 +03:00
_sel = 0 ;
refresh ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2014-11-25 15:15:29 +03:00
if ( ! _addContactLnk . isHidden ( ) ) _addContactLnk . hide ( ) ;
2014-05-30 12:53:19 +04:00
QStringList : : const_iterator fb = f . cbegin ( ) , fe = f . cend ( ) , fi ;
_filtered . clear ( ) ;
if ( ! f . isEmpty ( ) ) {
DialogsList * dialogsToFilter = 0 ;
if ( _contacts - > list . count ) {
for ( fi = fb ; fi ! = fe ; + + fi ) {
DialogsIndexed : : DialogsIndex : : iterator i = _contacts - > index . find ( fi - > at ( 0 ) ) ;
if ( i = = _contacts - > index . cend ( ) ) {
dialogsToFilter = 0 ;
break ;
}
if ( ! dialogsToFilter | | dialogsToFilter - > count > i . value ( ) - > count ) {
dialogsToFilter = i . value ( ) ;
}
}
}
if ( dialogsToFilter & & dialogsToFilter - > count ) {
_filtered . reserve ( dialogsToFilter - > count ) ;
for ( DialogRow * i = dialogsToFilter - > begin , * e = dialogsToFilter - > end ; i ! = e ; i = i - > next ) {
const PeerData : : Names & names ( i - > history - > peer - > names ) ;
PeerData : : Names : : const_iterator nb = names . cbegin ( ) , ne = names . cend ( ) , ni ;
for ( fi = fb ; fi ! = fe ; + + fi ) {
QString filterName ( * fi ) ;
for ( ni = nb ; ni ! = ne ; + + ni ) {
2014-08-22 13:53:53 +04:00
if ( ni - > startsWith ( * fi ) ) {
2014-05-30 12:53:19 +04:00
break ;
}
}
if ( ni = = ne ) {
break ;
}
}
if ( fi = = fe ) {
i - > attached = 0 ;
_filtered . push_back ( i ) ;
}
}
}
2015-04-02 13:33:19 +03:00
_byUsernameFiltered . reserve ( _byUsername . size ( ) ) ;
d_byUsernameFiltered . reserve ( d_byUsername . size ( ) ) ;
for ( int32 i = 0 , l = _byUsername . size ( ) ; i < l ; + + i ) {
const PeerData : : Names & names ( _byUsername [ i ] - > names ) ;
PeerData : : Names : : const_iterator nb = names . cbegin ( ) , ne = names . cend ( ) , ni ;
for ( fi = fb ; fi ! = fe ; + + fi ) {
QString filterName ( * fi ) ;
for ( ni = nb ; ni ! = ne ; + + ni ) {
if ( ni - > startsWith ( * fi ) ) {
break ;
}
}
if ( ni = = ne ) {
break ;
}
}
if ( fi = = fe ) {
_byUsernameFiltered . push_back ( _byUsername [ i ] ) ;
d_byUsernameFiltered . push_back ( d_byUsername [ i ] ) ;
}
}
}
_filteredSel = - 1 ;
2014-11-25 15:15:29 +03:00
if ( ! _filtered . isEmpty ( ) ) {
2015-04-02 13:33:19 +03:00
for ( _filteredSel = 0 ; ( _filteredSel < _filtered . size ( ) ) & & contactData ( _filtered [ _filteredSel ] ) - > inchat ; ) {
+ + _filteredSel ;
}
if ( _filteredSel = = _filtered . size ( ) ) _filteredSel = - 1 ;
}
_byUsernameSel = - 1 ;
if ( _filteredSel < 0 & & ! _byUsernameFiltered . isEmpty ( ) ) {
for ( _byUsernameSel = 0 ; ( _byUsernameSel < _byUsernameFiltered . size ( ) ) & & d_byUsernameFiltered [ _byUsernameSel ] - > inchat ; ) {
+ + _byUsernameSel ;
}
if ( _byUsernameSel = = _byUsernameFiltered . size ( ) ) _byUsernameSel = - 1 ;
2014-11-25 15:15:29 +03:00
}
2015-10-11 10:37:24 +02:00
_mouseSel = false ;
2015-04-02 13:33:19 +03:00
refresh ( ) ;
2015-06-15 20:19:24 +03:00
if ( ! bot ( ) ) {
_searching = true ;
emit searchByUsername ( ) ;
}
2014-05-30 12:53:19 +04:00
}
2015-10-01 17:05:05 +03:00
update ( ) ;
2014-05-30 12:53:19 +04:00
loadProfilePhotos ( 0 ) ;
}
}
void ContactsInner : : onDialogRowReplaced ( DialogRow * oldRow , DialogRow * newRow ) {
if ( ! _filter . isEmpty ( ) ) {
for ( FilteredDialogs : : iterator i = _filtered . begin ( ) , e = _filtered . end ( ) ; i ! = e ; ) {
if ( * i = = oldRow ) { // this row is shown in filtered and maybe is in contacts!
if ( newRow ) {
* i = newRow ;
+ + i ;
} else {
i = _filtered . erase ( i ) ;
}
} else {
+ + i ;
}
}
if ( _filteredSel > = _filtered . size ( ) ) {
_filteredSel = - 1 ;
}
} else {
if ( _sel = = oldRow ) {
_sel = newRow ;
}
}
_mouseSel = false ;
2014-11-25 15:15:29 +03:00
int32 cnt = ( _filter . isEmpty ( ) ? _contacts - > list . count : _filtered . size ( ) ) ;
2015-10-11 10:37:24 +02:00
int32 newh = cnt ? ( cnt * _rowHeight ) : st : : noContactsHeight ;
2014-05-30 12:53:19 +04:00
resize ( width ( ) , newh ) ;
}
2015-09-06 13:17:09 +03:00
void ContactsInner : : peopleReceived ( const QString & query , const QVector < MTPPeer > & people ) {
2015-04-02 13:33:19 +03:00
_lastQuery = query . toLower ( ) . trimmed ( ) ;
if ( _lastQuery . at ( 0 ) = = ' @ ' ) _lastQuery = _lastQuery . mid ( 1 ) ;
int32 already = _byUsernameFiltered . size ( ) ;
_byUsernameFiltered . reserve ( already + people . size ( ) ) ;
d_byUsernameFiltered . reserve ( already + people . size ( ) ) ;
2015-09-06 13:17:09 +03:00
for ( QVector < MTPPeer > : : const_iterator i = people . cbegin ( ) , e = people . cend ( ) ; i ! = e ; + + i ) {
PeerId peerId = peerFromMTP ( * i ) ;
int32 j = 0 ;
2015-04-02 13:33:19 +03:00
for ( ; j < already ; + + j ) {
2015-09-06 13:17:09 +03:00
if ( _byUsernameFiltered [ j ] - > id = = peerId ) break ;
2015-04-02 13:33:19 +03:00
}
if ( j = = already ) {
2015-09-06 13:17:09 +03:00
PeerData * p = App : : peer ( peerId ) ;
if ( ! p ) continue ;
2015-10-11 10:37:24 +02:00
if ( ( ! p - > isUser ( ) | | ( p - > asUser ( ) - > botInfo & & p - > asUser ( ) - > botInfo - > cantJoinGroups ) ) & & ( _chat | | _creating = = CreatingGroupGroup ) ) continue ; // skip bot's that can't be invited to groups
if ( _channel & & ! p - > isUser ( ) ) continue ;
if ( p - > isUser ( ) & & p - > asUser ( ) - > botInfo & & _channel & & _channelFilter ! = MembersFilterAdmins ) continue ; // skip bots in channels
2015-06-15 20:19:24 +03:00
2015-04-02 13:33:19 +03:00
ContactData * d = new ContactData ( ) ;
_byUsernameDatas . push_back ( d ) ;
2015-09-16 16:04:08 +03:00
d - > inchat = _chat ? _chat - > participants . contains ( p - > asUser ( ) ) : ( ( _creating = = CreatingGroupGroup | | _channel ) ? ( p = = App : : self ( ) ) : false ) ;
2015-09-06 13:17:09 +03:00
d - > check = _checkedContacts . contains ( p ) ;
2015-10-11 10:37:24 +02:00
d - > name . setText ( st : : contactsNameFont , p - > name , _textNameOptions ) ;
2015-09-06 13:17:09 +03:00
d - > online = ' @ ' + p - > userName ( ) ;
2015-04-02 13:33:19 +03:00
2015-09-06 13:17:09 +03:00
_byUsernameFiltered . push_back ( p ) ;
2015-04-02 13:33:19 +03:00
d_byUsernameFiltered . push_back ( d ) ;
}
}
_searching = false ;
refresh ( ) ;
}
void ContactsInner : : refresh ( ) {
if ( _filter . isEmpty ( ) ) {
if ( _contacts - > list . count | | ! _byUsername . isEmpty ( ) ) {
if ( ! _addContactLnk . isHidden ( ) ) _addContactLnk . hide ( ) ;
2015-10-11 10:37:24 +02:00
resize ( width ( ) , _newItemHeight + ( _contacts - > list . count * _rowHeight ) + ( _byUsername . isEmpty ( ) ? 0 : ( st : : searchedBarHeight + _byUsername . size ( ) * _rowHeight ) ) ) ;
2015-04-02 13:33:19 +03:00
} else {
2015-06-15 20:19:24 +03:00
if ( cContactsReceived ( ) & & ! bot ( ) ) {
2015-04-02 13:33:19 +03:00
if ( _addContactLnk . isHidden ( ) ) _addContactLnk . show ( ) ;
} else {
if ( ! _addContactLnk . isHidden ( ) ) _addContactLnk . hide ( ) ;
}
resize ( width ( ) , st : : noContactsHeight ) ;
}
} else {
if ( _filtered . isEmpty ( ) & & _byUsernameFiltered . isEmpty ( ) ) {
if ( ! _addContactLnk . isHidden ( ) ) _addContactLnk . hide ( ) ;
resize ( width ( ) , st : : noContactsHeight ) ;
} else {
2015-10-11 10:37:24 +02:00
resize ( width ( ) , ( _filtered . size ( ) * _rowHeight ) + ( _byUsernameFiltered . isEmpty ( ) ? 0 : ( st : : searchedBarHeight + _byUsernameFiltered . size ( ) * _rowHeight ) ) ) ;
2015-04-02 13:33:19 +03:00
}
}
update ( ) ;
}
ChatData * ContactsInner : : chat ( ) const {
return _chat ;
}
2015-09-16 16:04:08 +03:00
ChannelData * ContactsInner : : channel ( ) const {
return _channel ;
}
2015-09-23 20:43:08 +03:00
MembersFilter ContactsInner : : channelFilter ( ) const {
return _channelFilter ;
}
2015-06-15 20:19:24 +03:00
UserData * ContactsInner : : bot ( ) const {
return _bot ;
}
2015-09-16 16:04:08 +03:00
CreatingGroupType ContactsInner : : creating ( ) const {
return _creating ;
2015-04-02 13:33:19 +03:00
}
2014-05-30 12:53:19 +04:00
ContactsInner : : ~ ContactsInner ( ) {
for ( ContactsData : : iterator i = _contactsData . begin ( ) , e = _contactsData . end ( ) ; i ! = e ; + + i ) {
delete * i ;
}
2015-06-17 22:43:03 +03:00
if ( _bot ) {
delete _contacts ;
if ( _bot - > botInfo ) _bot - > botInfo - > startGroupToken = QString ( ) ;
}
2014-05-30 12:53:19 +04:00
}
2014-11-25 15:15:29 +03:00
void ContactsInner : : resizeEvent ( QResizeEvent * e ) {
_addContactLnk . move ( ( width ( ) - _addContactLnk . width ( ) ) / 2 , ( st : : noContactsHeight + st : : noContactsFont - > height ) / 2 ) ;
}
2014-05-30 12:53:19 +04:00
void ContactsInner : : selectSkip ( int32 dir ) {
2015-04-02 13:33:19 +03:00
_time = unixtime ( ) ;
2014-05-30 12:53:19 +04:00
_mouseSel = false ;
if ( _filter . isEmpty ( ) ) {
2015-04-02 13:33:19 +03:00
int cur = 0 ;
2014-05-30 12:53:19 +04:00
if ( _sel ) {
2015-04-02 13:33:19 +03:00
for ( DialogRow * i = _contacts - > list . begin ; i ! = _sel ; i = i - > next ) {
+ + cur ;
}
2015-10-11 10:37:24 +02:00
if ( _newItemHeight ) + + cur ;
} else if ( _byUsernameSel > = 0 ) {
cur = ( _contacts - > list . count + _byUsernameSel ) ;
if ( _newItemHeight ) + + cur ;
} else if ( ! _newItemSel ) {
cur = - 1 ;
2015-04-02 13:33:19 +03:00
}
cur + = dir ;
if ( cur < = 0 ) {
2015-10-11 10:37:24 +02:00
_newItemSel = _newItemHeight ? true : false ;
_sel = ( ! _newItemHeight & & _contacts - > list . count ) ? _contacts - > list . begin : 0 ;
_byUsernameSel = ( ! _newItemHeight & & ! _contacts - > list . count & & ! _byUsername . isEmpty ( ) ) ? 0 : - 1 ;
} else if ( cur > = _contacts - > list . count + ( _newItemHeight ? 1 : 0 ) ) {
_newItemSel = false ;
2015-04-02 13:33:19 +03:00
if ( _byUsername . isEmpty ( ) ) {
_sel = _contacts - > list . count ? _contacts - > list . end - > prev : 0 ;
_byUsernameSel = - 1 ;
2014-05-30 12:53:19 +04:00
} else {
2015-04-02 13:33:19 +03:00
_sel = 0 ;
_byUsernameSel = cur - _contacts - > list . count ;
if ( _byUsernameSel > = _byUsername . size ( ) ) _byUsernameSel = _byUsername . size ( ) - 1 ;
}
} else {
2015-10-11 10:37:24 +02:00
_newItemSel = false ;
if ( _newItemHeight ) - - cur ;
2015-04-02 13:33:19 +03:00
for ( _sel = _contacts - > list . begin ; cur ; _sel = _sel - > next ) {
- - cur ;
}
_byUsernameSel = - 1 ;
}
if ( dir > 0 ) {
while ( _sel & & _sel - > next & & contactData ( _sel ) - > inchat ) {
_sel = _sel - > next ;
}
if ( ! _sel | | ! _sel - > next ) {
_sel = 0 ;
if ( ! _byUsername . isEmpty ( ) ) {
if ( _byUsernameSel < 0 ) _byUsernameSel = 0 ;
for ( ; _byUsernameSel < _byUsername . size ( ) & & d_byUsername [ _byUsernameSel ] - > inchat ; ) {
+ + _byUsernameSel ;
}
if ( _byUsernameSel = = _byUsername . size ( ) ) _byUsernameSel = - 1 ;
}
}
} else {
while ( _byUsernameSel > = 0 & & d_byUsername [ _byUsernameSel ] - > inchat ) {
- - _byUsernameSel ;
}
if ( _byUsernameSel < 0 ) {
if ( _contacts - > list . count ) {
2015-10-11 10:37:24 +02:00
if ( ! _newItemSel & & ! _sel ) _sel = _contacts - > list . end - > prev ;
2015-04-02 13:33:19 +03:00
for ( ; _sel & & contactData ( _sel ) - > inchat ; ) {
_sel = _sel - > prev ;
}
2014-05-30 12:53:19 +04:00
}
}
}
2015-10-11 10:37:24 +02:00
if ( _newItemSel ) {
emit mustScrollTo ( 0 , _newItemHeight ) ;
} else if ( _sel ) {
emit mustScrollTo ( _newItemHeight + _sel - > pos * _rowHeight , _newItemHeight + ( _sel - > pos + 1 ) * _rowHeight ) ;
2015-04-02 13:33:19 +03:00
} else if ( _byUsernameSel > = 0 ) {
2015-10-11 10:37:24 +02:00
emit mustScrollTo ( _newItemHeight + ( _contacts - > list . count + _byUsernameSel ) * _rowHeight + st : : searchedBarHeight , _newItemHeight + ( _contacts - > list . count + _byUsernameSel + 1 ) * _rowHeight + st : : searchedBarHeight ) ;
2014-05-30 12:53:19 +04:00
}
} else {
2015-04-02 13:33:19 +03:00
int cur = ( _filteredSel > = 0 ) ? _filteredSel : ( ( _byUsernameSel > = 0 ) ? ( _filtered . size ( ) + _byUsernameSel ) : - 1 ) ;
cur + = dir ;
if ( cur < = 0 ) {
_filteredSel = _filtered . isEmpty ( ) ? - 1 : 0 ;
_byUsernameSel = ( _filtered . isEmpty ( ) & & ! _byUsernameFiltered . isEmpty ( ) ) ? 0 : - 1 ;
} else if ( cur > = _filtered . size ( ) ) {
_filteredSel = - 1 ;
_byUsernameSel = cur - _filtered . size ( ) ;
if ( _byUsernameSel > = _byUsernameFiltered . size ( ) ) _byUsernameSel = _byUsernameFiltered . size ( ) - 1 ;
} else {
_filteredSel = cur ;
_byUsernameSel = - 1 ;
}
2014-05-30 12:53:19 +04:00
if ( dir > 0 ) {
2015-04-02 13:33:19 +03:00
while ( _filteredSel > = 0 & & _filteredSel < _filtered . size ( ) & & contactData ( _filtered [ _filteredSel ] ) - > inchat ) {
+ + _filteredSel ;
2014-05-30 12:53:19 +04:00
}
2015-04-02 13:33:19 +03:00
if ( _filteredSel < 0 | | _filteredSel > = _filtered . size ( ) ) {
_filteredSel = - 1 ;
if ( ! _byUsernameFiltered . isEmpty ( ) ) {
if ( _byUsernameSel < 0 ) _byUsernameSel = 0 ;
for ( ; _byUsernameSel < _byUsernameFiltered . size ( ) & & d_byUsernameFiltered [ _byUsernameSel ] - > inchat ; ) {
+ + _byUsernameSel ;
}
if ( _byUsernameSel = = _byUsernameFiltered . size ( ) ) _byUsernameSel = - 1 ;
}
2014-05-30 12:53:19 +04:00
}
2015-04-02 13:33:19 +03:00
} else {
while ( _byUsernameSel > = 0 & & d_byUsernameFiltered [ _byUsernameSel ] - > inchat ) {
- - _byUsernameSel ;
}
if ( _byUsernameSel < 0 ) {
if ( ! _filtered . isEmpty ( ) ) {
if ( _filteredSel < 0 ) _filteredSel = _filtered . size ( ) - 1 ;
for ( ; _filteredSel > = 0 & & contactData ( _filtered [ _filteredSel ] ) - > inchat ; ) {
- - _filteredSel ;
}
}
2014-05-30 12:53:19 +04:00
}
}
if ( _filteredSel > = 0 ) {
2015-10-11 10:37:24 +02:00
emit mustScrollTo ( _filteredSel * _rowHeight , ( _filteredSel + 1 ) * _rowHeight ) ;
2015-04-02 13:33:19 +03:00
} else if ( _byUsernameSel > = 0 ) {
2015-10-11 10:37:24 +02:00
int skip = _filtered . size ( ) * _rowHeight + st : : searchedBarHeight ;
emit mustScrollTo ( skip + _byUsernameSel * _rowHeight , skip + ( _byUsernameSel + 1 ) * _rowHeight ) ;
2014-05-30 12:53:19 +04:00
}
}
2015-10-01 17:05:05 +03:00
update ( ) ;
2014-05-30 12:53:19 +04:00
}
void ContactsInner : : selectSkipPage ( int32 h , int32 dir ) {
2015-10-11 10:37:24 +02:00
int32 points = h / _rowHeight ;
2014-05-30 12:53:19 +04:00
if ( ! points ) return ;
selectSkip ( points * dir ) ;
}
2015-04-02 13:33:19 +03:00
QVector < UserData * > ContactsInner : : selected ( ) {
QVector < UserData * > result ;
2015-08-07 15:11:50 +03:00
for ( DialogRow * row = _contacts - > list . begin ; row - > next ; row = row - > next ) {
if ( _checkedContacts . contains ( row - > history - > peer ) ) {
contactData ( row ) ; // fill _contactsData
}
}
2015-04-02 13:33:19 +03:00
result . reserve ( _contactsData . size ( ) ) ;
for ( ContactsData : : const_iterator i = _contactsData . cbegin ( ) , e = _contactsData . cend ( ) ; i ! = e ; + + i ) {
2015-09-03 13:48:40 +03:00
if ( i . value ( ) - > check & & i . key ( ) - > isUser ( ) ) {
2015-06-15 20:19:24 +03:00
result . push_back ( i . key ( ) - > asUser ( ) ) ;
2015-04-02 13:33:19 +03:00
}
}
for ( int32 i = 0 , l = _byUsername . size ( ) ; i < l ; + + i ) {
2015-09-06 13:17:09 +03:00
if ( d_byUsername [ i ] - > check & & _byUsername [ i ] - > isUser ( ) ) {
result . push_back ( _byUsername [ i ] - > asUser ( ) ) ;
2015-04-02 13:33:19 +03:00
}
}
return result ;
}
2014-05-30 12:53:19 +04:00
2015-04-02 13:33:19 +03:00
QVector < MTPInputUser > ContactsInner : : selectedInputs ( ) {
QVector < MTPInputUser > result ;
2015-08-07 15:11:50 +03:00
for ( DialogRow * row = _contacts - > list . begin ; row - > next ; row = row - > next ) {
if ( _checkedContacts . contains ( row - > history - > peer ) ) {
contactData ( row ) ; // fill _contactsData
}
}
2015-04-02 13:33:19 +03:00
result . reserve ( _contactsData . size ( ) ) ;
for ( ContactsData : : const_iterator i = _contactsData . cbegin ( ) , e = _contactsData . cend ( ) ; i ! = e ; + + i ) {
2015-09-03 13:48:40 +03:00
if ( i . value ( ) - > check & & i . key ( ) - > isUser ( ) ) {
2015-08-07 15:11:50 +03:00
result . push_back ( i . key ( ) - > asUser ( ) - > inputUser ) ;
2015-04-02 13:33:19 +03:00
}
}
for ( int32 i = 0 , l = _byUsername . size ( ) ; i < l ; + + i ) {
2015-09-06 13:17:09 +03:00
if ( d_byUsername [ i ] - > check & & _byUsername [ i ] - > isUser ( ) ) {
result . push_back ( _byUsername [ i ] - > asUser ( ) - > inputUser ) ;
2015-04-02 13:33:19 +03:00
}
}
return result ;
}
2014-05-30 12:53:19 +04:00
2015-04-02 13:33:19 +03:00
PeerData * ContactsInner : : selectedUser ( ) {
2015-08-07 15:11:50 +03:00
for ( DialogRow * row = _contacts - > list . begin ; row - > next ; row = row - > next ) {
if ( _checkedContacts . contains ( row - > history - > peer ) ) {
contactData ( row ) ; // fill _contactsData
}
}
2015-04-02 13:33:19 +03:00
for ( ContactsData : : const_iterator i = _contactsData . cbegin ( ) , e = _contactsData . cend ( ) ; i ! = e ; + + i ) {
if ( i . value ( ) - > check ) {
return i . key ( ) ;
}
}
for ( int32 i = 0 , l = _byUsername . size ( ) ; i < l ; + + i ) {
if ( d_byUsername [ i ] - > check ) {
return _byUsername [ i ] ;
}
}
return 0 ;
}
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
ContactsBox : : ContactsBox ( ) : ItemListBox ( st : : contactsScroll )
, _inner ( CreatingGroupNone )
, _filter ( this , st : : boxSearchField , lang ( lng_participant_filter ) )
, _filterCancel ( this , st : : boxSearchCancel )
, _next ( this , lang ( lng_create_group_next ) , st : : defaultBoxButton )
2015-10-12 23:02:10 +02:00
, _cancel ( this , lang ( lng_cancel ) , st : : cancelBoxButton )
2015-10-11 10:37:24 +02:00
, _topShadow ( this )
, _bottomShadow ( 0 )
, _creationRequestId ( 0 ) {
2015-09-16 16:04:08 +03:00
init ( ) ;
}
2015-10-11 10:37:24 +02:00
ContactsBox : : ContactsBox ( const QString & name , const QImage & photo ) : ItemListBox ( st : : boxScroll )
, _inner ( CreatingGroupGroup )
, _filter ( this , st : : boxSearchField , lang ( lng_participant_filter ) )
, _filterCancel ( this , st : : boxSearchCancel )
, _next ( this , lang ( lng_create_group_create ) , st : : defaultBoxButton )
, _cancel ( this , lang ( lng_create_group_back ) , st : : cancelBoxButton )
, _topShadow ( this )
, _bottomShadow ( 0 )
, _creationRequestId ( 0 )
, _creationName ( name )
, _creationPhoto ( photo ) {
2015-09-16 16:04:08 +03:00
init ( ) ;
}
2015-10-11 10:37:24 +02:00
ContactsBox : : ContactsBox ( ChannelData * channel ) : ItemListBox ( st : : boxScroll )
, _inner ( channel )
, _filter ( this , st : : boxSearchField , lang ( lng_participant_filter ) )
, _filterCancel ( this , st : : boxSearchCancel )
, _next ( this , lang ( lng_participant_invite ) , st : : defaultBoxButton )
, _cancel ( this , lang ( lng_create_group_skip ) , st : : cancelBoxButton )
, _topShadow ( this )
, _bottomShadow ( 0 )
, _creationRequestId ( 0 ) {
2015-04-02 13:33:19 +03:00
init ( ) ;
}
2015-10-11 10:37:24 +02:00
ContactsBox : : ContactsBox ( ChannelData * channel , MembersFilter filter , const MembersAlreadyIn & already ) : ItemListBox ( ( filter = = MembersFilterAdmins ) ? st : : contactsScroll : st : : boxScroll )
, _inner ( channel , filter , already )
, _filter ( this , st : : boxSearchField , lang ( lng_participant_filter ) )
, _filterCancel ( this , st : : boxSearchCancel )
, _next ( this , lang ( lng_participant_invite ) , st : : defaultBoxButton )
2015-10-12 23:02:10 +02:00
, _cancel ( this , lang ( lng_cancel ) , st : : cancelBoxButton )
2015-10-11 10:37:24 +02:00
, _topShadow ( this )
, _bottomShadow ( 0 )
, _creationRequestId ( 0 ) {
2015-09-23 20:43:08 +03:00
init ( ) ;
}
2015-10-11 10:37:24 +02:00
ContactsBox : : ContactsBox ( ChatData * chat ) : ItemListBox ( st : : boxScroll )
, _inner ( chat )
, _filter ( this , st : : boxSearchField , lang ( lng_participant_filter ) )
, _filterCancel ( this , st : : boxSearchCancel )
, _next ( this , lang ( lng_participant_invite ) , st : : defaultBoxButton )
, _cancel ( this , lang ( lng_cancel ) , st : : cancelBoxButton )
, _topShadow ( this )
, _bottomShadow ( 0 )
, _creationRequestId ( 0 ) {
2015-04-02 13:33:19 +03:00
init ( ) ;
}
2015-10-11 10:37:24 +02:00
ContactsBox : : ContactsBox ( UserData * bot ) : ItemListBox ( st : : contactsScroll )
, _inner ( bot )
, _filter ( this , st : : boxSearchField , lang ( lng_participant_filter ) )
, _filterCancel ( this , st : : boxSearchCancel )
, _next ( this , lang ( lng_create_group_next ) , st : : defaultBoxButton )
, _cancel ( this , lang ( lng_cancel ) , st : : cancelBoxButton )
, _topShadow ( this )
, _bottomShadow ( 0 )
, _creationRequestId ( 0 ) {
2015-06-15 20:19:24 +03:00
init ( ) ;
}
2015-04-02 13:33:19 +03:00
void ContactsBox : : init ( ) {
2015-10-11 10:37:24 +02:00
bool inviting = ( _inner . creating ( ) = = CreatingGroupGroup ) | | ( _inner . channel ( ) & & _inner . channelFilter ( ) = = MembersFilterRecent ) | | _inner . chat ( ) ;
int32 topSkip = st : : boxTitleHeight + _filter . height ( ) ;
int32 bottomSkip = inviting ? ( st : : boxButtonPadding . top ( ) + _next . height ( ) + st : : boxButtonPadding . bottom ( ) ) : st : : boxScrollSkip ;
ItemListBox : : init ( & _inner , bottomSkip , topSkip ) ;
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
connect ( & _inner , SIGNAL ( chosenChanged ( ) ) , this , SLOT ( onChosenChanged ( ) ) ) ;
connect ( & _inner , SIGNAL ( addRequested ( ) ) , App : : wnd ( ) , SLOT ( onShowAddContact ( ) ) ) ;
2015-09-16 16:04:08 +03:00
if ( _inner . chat ( ) | | _inner . channel ( ) ) {
2015-04-02 13:33:19 +03:00
connect ( & _next , SIGNAL ( clicked ( ) ) , this , SLOT ( onInvite ( ) ) ) ;
2015-10-11 10:37:24 +02:00
_bottomShadow = new ScrollableBoxShadow ( this ) ;
2015-09-16 16:04:08 +03:00
} else if ( _inner . creating ( ) ! = CreatingGroupNone ) {
connect ( & _next , SIGNAL ( clicked ( ) ) , this , SLOT ( onCreate ( ) ) ) ;
2015-10-11 10:37:24 +02:00
_bottomShadow = new ScrollableBoxShadow ( this ) ;
2015-04-02 13:33:19 +03:00
} else {
_next . hide ( ) ;
2015-10-11 10:37:24 +02:00
_cancel . hide ( ) ;
2015-04-02 13:33:19 +03:00
}
connect ( & _cancel , SIGNAL ( clicked ( ) ) , this , SLOT ( onClose ( ) ) ) ;
2014-05-30 12:53:19 +04:00
connect ( & _scroll , SIGNAL ( scrolled ( ) ) , & _inner , SLOT ( updateSel ( ) ) ) ;
connect ( & _scroll , SIGNAL ( scrolled ( ) ) , this , SLOT ( onScroll ( ) ) ) ;
connect ( & _filter , SIGNAL ( changed ( ) ) , this , SLOT ( onFilterUpdate ( ) ) ) ;
2015-10-11 10:37:24 +02:00
connect ( & _filterCancel , SIGNAL ( clicked ( ) ) , this , SLOT ( onFilterCancel ( ) ) ) ;
2015-04-02 13:33:19 +03:00
connect ( & _inner , SIGNAL ( mustScrollTo ( int , int ) ) , & _scroll , SLOT ( scrollToY ( int , int ) ) ) ;
connect ( & _inner , SIGNAL ( selectAllQuery ( ) ) , & _filter , SLOT ( selectAll ( ) ) ) ;
connect ( & _inner , SIGNAL ( searchByUsername ( ) ) , this , SLOT ( onNeedSearchByUsername ( ) ) ) ;
2015-09-23 20:43:08 +03:00
connect ( & _inner , SIGNAL ( adminAdded ( ) ) , this , SIGNAL ( adminAdded ( ) ) ) ;
2014-05-30 12:53:19 +04:00
2015-10-11 10:37:24 +02:00
_filterCancel . setAttribute ( Qt : : WA_OpaquePaintEvent ) ;
2015-04-02 13:33:19 +03:00
_searchTimer . setSingleShot ( true ) ;
connect ( & _searchTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onSearchByUsername ( ) ) ) ;
prepare ( ) ;
}
bool ContactsBox : : onSearchByUsername ( bool searchCache ) {
2015-10-11 10:37:24 +02:00
QString q = _filter . getLastText ( ) . trimmed ( ) ;
2015-04-02 13:33:19 +03:00
if ( q . isEmpty ( ) ) {
if ( _peopleRequest ) {
_peopleRequest = 0 ;
}
return true ;
}
if ( q . size ( ) > = MinUsernameLength ) {
if ( searchCache ) {
PeopleCache : : const_iterator i = _peopleCache . constFind ( q ) ;
if ( i ! = _peopleCache . cend ( ) ) {
_peopleQuery = q ;
_peopleRequest = 0 ;
peopleReceived ( i . value ( ) , 0 ) ;
return true ;
}
} else if ( _peopleQuery ! = q ) {
_peopleQuery = q ;
_peopleFull = false ;
_peopleRequest = MTP : : send ( MTPcontacts_Search ( MTP_string ( _peopleQuery ) , MTP_int ( SearchPeopleLimit ) ) , rpcDone ( & ContactsBox : : peopleReceived ) , rpcFail ( & ContactsBox : : peopleFailed ) ) ;
_peopleQueries . insert ( _peopleRequest , _peopleQuery ) ;
}
}
return false ;
}
void ContactsBox : : onNeedSearchByUsername ( ) {
if ( ! onSearchByUsername ( true ) ) {
_searchTimer . start ( AutoSearchTimeout ) ;
}
}
void ContactsBox : : peopleReceived ( const MTPcontacts_Found & result , mtpRequestId req ) {
QString q = _peopleQuery ;
PeopleQueries : : iterator i = _peopleQueries . find ( req ) ;
if ( i ! = _peopleQueries . cend ( ) ) {
q = i . value ( ) ;
_peopleCache [ q ] = result ;
_peopleQueries . erase ( i ) ;
}
if ( _peopleRequest = = req ) {
switch ( result . type ( ) ) {
case mtpc_contacts_found : {
App : : feedUsers ( result . c_contacts_found ( ) . vusers ) ;
2015-09-21 23:57:42 +03:00
App : : feedChats ( result . c_contacts_found ( ) . vchats ) ;
2015-04-02 13:33:19 +03:00
_inner . peopleReceived ( q , result . c_contacts_found ( ) . vresults . c_vector ( ) . v ) ;
} break ;
}
_peopleRequest = 0 ;
_inner . updateSel ( ) ;
onScroll ( ) ;
}
}
bool ContactsBox : : peopleFailed ( const RPCError & error , mtpRequestId req ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2015-04-02 13:33:19 +03:00
if ( _peopleRequest = = req ) {
_peopleRequest = 0 ;
_peopleFull = true ;
}
return true ;
2014-05-30 12:53:19 +04:00
}
void ContactsBox : : hideAll ( ) {
_filter . hide ( ) ;
2015-10-11 10:37:24 +02:00
_filterCancel . hide ( ) ;
2015-04-02 13:33:19 +03:00
_next . hide ( ) ;
_cancel . hide ( ) ;
2015-10-11 10:37:24 +02:00
_topShadow . hide ( ) ;
if ( _bottomShadow ) _bottomShadow - > hide ( ) ;
ItemListBox : : hideAll ( ) ;
2014-05-30 12:53:19 +04:00
}
void ContactsBox : : showAll ( ) {
_filter . show ( ) ;
2015-10-11 10:37:24 +02:00
if ( _filter . getLastText ( ) . isEmpty ( ) ) {
_filterCancel . hide ( ) ;
} else {
_filterCancel . show ( ) ;
}
2015-09-23 20:43:08 +03:00
if ( _inner . channel ( ) & & _inner . channelFilter ( ) = = MembersFilterAdmins ) {
_next . hide ( ) ;
2015-10-11 10:37:24 +02:00
_cancel . hide ( ) ;
2015-09-23 20:43:08 +03:00
} else if ( _inner . chat ( ) ) {
2015-04-02 13:33:19 +03:00
_next . show ( ) ;
2015-10-11 10:37:24 +02:00
_cancel . show ( ) ;
2015-09-16 16:04:08 +03:00
} else if ( _inner . creating ( ) ! = CreatingGroupNone ) {
2015-09-06 13:17:09 +03:00
_next . show ( ) ;
2015-10-11 10:37:24 +02:00
_cancel . show ( ) ;
2015-04-02 13:33:19 +03:00
} else {
_next . hide ( ) ;
2015-10-11 10:37:24 +02:00
_cancel . hide ( ) ;
2015-04-02 13:33:19 +03:00
}
2015-10-11 10:37:24 +02:00
_topShadow . show ( ) ;
if ( _bottomShadow ) _bottomShadow - > show ( ) ;
ItemListBox : : showAll ( ) ;
2015-04-02 13:33:19 +03:00
}
void ContactsBox : : showDone ( ) {
_filter . setFocus ( ) ;
2014-05-30 12:53:19 +04:00
}
void ContactsBox : : keyPressEvent ( QKeyEvent * e ) {
2015-04-02 13:33:19 +03:00
if ( e - > key ( ) = = Qt : : Key_Return | | e - > key ( ) = = Qt : : Key_Enter ) {
2014-05-30 12:53:19 +04:00
if ( _filter . hasFocus ( ) ) {
_inner . chooseParticipant ( ) ;
2015-04-02 13:33:19 +03:00
} else {
ItemListBox : : keyPressEvent ( e ) ;
2014-05-30 12:53:19 +04:00
}
} else if ( _filter . hasFocus ( ) ) {
if ( e - > key ( ) = = Qt : : Key_Down ) {
_inner . selectSkip ( 1 ) ;
} else if ( e - > key ( ) = = Qt : : Key_Up ) {
_inner . selectSkip ( - 1 ) ;
} else if ( e - > key ( ) = = Qt : : Key_PageDown ) {
_inner . selectSkipPage ( _scroll . height ( ) , 1 ) ;
} else if ( e - > key ( ) = = Qt : : Key_PageUp ) {
_inner . selectSkipPage ( _scroll . height ( ) , - 1 ) ;
} else {
2015-04-02 13:33:19 +03:00
ItemListBox : : keyPressEvent ( e ) ;
2014-05-30 12:53:19 +04:00
}
} else {
2015-04-02 13:33:19 +03:00
ItemListBox : : keyPressEvent ( e ) ;
2014-05-30 12:53:19 +04:00
}
}
void ContactsBox : : paintEvent ( QPaintEvent * e ) {
2015-04-04 23:01:34 +03:00
Painter p ( this ) ;
2015-04-02 13:33:19 +03:00
if ( paint ( p ) ) return ;
2014-05-30 12:53:19 +04:00
2015-09-23 20:43:08 +03:00
bool addingAdmin = _inner . channel ( ) & & _inner . channelFilter ( ) = = MembersFilterAdmins ;
2015-09-16 16:04:08 +03:00
if ( _inner . chat ( ) | | _inner . creating ( ) ! = CreatingGroupNone ) {
2015-09-23 20:43:08 +03:00
QString title ( lang ( addingAdmin ? lng_channel_add_admin : lng_profile_add_participant ) ) ;
2015-10-11 10:37:24 +02:00
QString additional ( addingAdmin ? QString ( ) : QString ( " %1 / %2 " ) . arg ( _inner . selectedCount ( ) ) . arg ( cMaxGroupCount ( ) ) ) ;
paintTitle ( p , title , additional ) ;
2015-06-15 20:19:24 +03:00
} else if ( _inner . bot ( ) ) {
2015-10-11 10:37:24 +02:00
paintTitle ( p , lang ( lng_bot_choose_group ) ) ;
2014-05-30 12:53:19 +04:00
} else {
2015-10-11 10:37:24 +02:00
paintTitle ( p , lang ( lng_contacts_header ) ) ;
2014-05-30 12:53:19 +04:00
}
}
void ContactsBox : : resizeEvent ( QResizeEvent * e ) {
2015-04-02 13:33:19 +03:00
ItemListBox : : resizeEvent ( e ) ;
2015-10-11 10:37:24 +02:00
_filter . resize ( width ( ) , _filter . height ( ) ) ;
_filter . moveToLeft ( 0 , st : : boxTitleHeight ) ;
_filterCancel . moveToRight ( 0 , st : : boxTitleHeight ) ;
2015-04-02 13:33:19 +03:00
_inner . resize ( width ( ) , _inner . height ( ) ) ;
2015-10-11 10:37:24 +02:00
_next . moveToRight ( st : : boxButtonPadding . right ( ) , height ( ) - st : : boxButtonPadding . bottom ( ) - _next . height ( ) ) ;
_cancel . moveToRight ( st : : boxButtonPadding . right ( ) + _next . width ( ) + st : : boxButtonPadding . left ( ) , _next . y ( ) ) ;
_topShadow . setGeometry ( 0 , st : : boxTitleHeight + _filter . height ( ) , width ( ) , st : : lineWidth ) ;
if ( _bottomShadow ) _bottomShadow - > setGeometry ( 0 , height ( ) - st : : boxButtonPadding . bottom ( ) - _next . height ( ) - st : : boxButtonPadding . top ( ) - st : : lineWidth , width ( ) , st : : lineWidth ) ;
2014-05-30 12:53:19 +04:00
}
2015-09-16 16:04:08 +03:00
void ContactsBox : : closePressed ( ) {
2015-09-23 20:43:08 +03:00
if ( _inner . channel ( ) & & ! _inner . hasAlreadyMembersInChannel ( ) ) {
2015-09-16 16:04:08 +03:00
App : : main ( ) - > showPeerHistory ( _inner . channel ( ) - > id , ShowAtTheEndMsgId ) ;
}
}
2015-10-11 10:37:24 +02:00
void ContactsBox : : onFilterCancel ( ) {
_filter . setText ( QString ( ) ) ;
}
2014-05-30 12:53:19 +04:00
void ContactsBox : : onFilterUpdate ( ) {
_scroll . scrollToY ( 0 ) ;
2015-10-11 10:37:24 +02:00
if ( _filter . getLastText ( ) . isEmpty ( ) ) {
_filterCancel . hide ( ) ;
} else {
_filterCancel . show ( ) ;
}
_inner . updateFilter ( _filter . getLastText ( ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-10-11 10:37:24 +02:00
void ContactsBox : : onChosenChanged ( ) {
update ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-04-02 13:33:19 +03:00
void ContactsBox : : onInvite ( ) {
QVector < UserData * > users ( _inner . selected ( ) ) ;
if ( users . isEmpty ( ) ) {
_filter . setFocus ( ) ;
2015-10-11 10:37:24 +02:00
_filter . showError ( ) ;
2015-04-02 13:33:19 +03:00
return ;
}
2015-09-16 16:04:08 +03:00
App : : main ( ) - > addParticipants ( _inner . chat ( ) ? ( PeerData * ) _inner . chat ( ) : _inner . channel ( ) , users ) ;
if ( _inner . chat ( ) ) {
App : : wnd ( ) - > hideLayer ( ) ;
App : : main ( ) - > showPeerHistory ( _inner . chat ( ) - > id , ShowAtTheEndMsgId ) ;
} else {
onClose ( ) ;
}
2015-04-02 13:33:19 +03:00
}
2015-09-16 16:04:08 +03:00
void ContactsBox : : onCreate ( ) {
if ( _creationRequestId ) return ;
2015-04-02 13:33:19 +03:00
MTPVector < MTPInputUser > users ( MTP_vector < MTPInputUser > ( _inner . selectedInputs ( ) ) ) ;
const QVector < MTPInputUser > & v ( users . c_vector ( ) . v ) ;
2015-09-16 16:04:08 +03:00
if ( v . isEmpty ( ) | | ( v . size ( ) = = 1 & & v . at ( 0 ) . type ( ) = = mtpc_inputUserSelf ) ) {
2015-04-02 13:33:19 +03:00
_filter . setFocus ( ) ;
2015-10-11 10:37:24 +02:00
_filter . showError ( ) ;
2015-09-16 16:04:08 +03:00
return ;
2015-04-02 13:33:19 +03:00
}
2015-09-16 16:04:08 +03:00
_creationRequestId = MTP : : send ( MTPmessages_CreateChat ( MTP_vector < MTPInputUser > ( v ) , MTP_string ( _creationName ) ) , rpcDone ( & ContactsBox : : creationDone ) , rpcFail ( & ContactsBox : : creationFail ) ) ;
2014-05-30 12:53:19 +04:00
}
void ContactsBox : : onScroll ( ) {
_inner . loadProfilePhotos ( _scroll . scrollTop ( ) ) ;
}
2015-10-11 10:37:24 +02:00
void ContactsBox : : creationDone ( const MTPUpdates & updates ) {
App : : wnd ( ) - > hideLayer ( ) ;
2015-09-16 16:04:08 +03:00
2015-10-11 10:37:24 +02:00
App : : main ( ) - > sentUpdatesReceived ( updates ) ;
2015-09-16 16:04:08 +03:00
const QVector < MTPChat > * v = 0 ;
switch ( updates . type ( ) ) {
case mtpc_updates : v = & updates . c_updates ( ) . vchats . c_vector ( ) . v ; break ;
case mtpc_updatesCombined : v = & updates . c_updatesCombined ( ) . vchats . c_vector ( ) . v ; break ;
2015-10-11 10:37:24 +02:00
default : LOG ( ( " API Error: unexpected update cons %1 (ContactsBox::creationDone) " ) . arg ( updates . type ( ) ) ) ; break ;
2015-09-16 16:04:08 +03:00
}
2015-10-11 10:37:24 +02:00
PeerData * peer = 0 ;
2015-09-16 16:04:08 +03:00
if ( v & & ! v - > isEmpty ( ) & & v - > front ( ) . type ( ) = = mtpc_chat ) {
2015-10-11 10:37:24 +02:00
peer = App : : chat ( v - > front ( ) . c_chat ( ) . vid . v ) ;
if ( peer ) {
if ( ! _creationPhoto . isNull ( ) ) {
App : : app ( ) - > uploadProfilePhoto ( _creationPhoto , peer - > id ) ;
2015-09-16 16:04:08 +03:00
}
2015-10-11 10:37:24 +02:00
App : : main ( ) - > showPeerHistory ( peer - > id , ShowAtUnreadMsgId ) ;
2015-09-16 16:04:08 +03:00
}
2015-10-11 10:37:24 +02:00
} else {
LOG ( ( " API Error: chat not found in updates (ContactsBox::creationDone) " ) ) ;
2015-09-16 16:04:08 +03:00
}
}
bool ContactsBox : : creationFail ( const RPCError & error ) {
if ( mtpIsFlood ( error ) ) return false ;
_creationRequestId = 0 ;
if ( error . type ( ) = = " NO_CHAT_TITLE " ) {
emit closed ( ) ;
return true ;
} else if ( error . type ( ) = = " USERS_TOO_FEW " ) {
_filter . setFocus ( ) ;
2015-10-11 10:37:24 +02:00
_filter . showError ( ) ;
2015-09-16 16:04:08 +03:00
return true ;
} else if ( error . type ( ) = = " PEER_FLOOD " ) {
2015-10-03 13:09:09 +03:00
App : : wnd ( ) - > replaceLayer ( new InformBox ( lng_cant_invite_not_contact ( lt_more_info , textcmdLink ( qsl ( " https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts " ) , lang ( lng_cant_more_info ) ) ) ) ) ;
2015-09-16 16:04:08 +03:00
return true ;
}
return false ;
}
2015-10-11 10:37:24 +02:00
MembersInner : : MembersInner ( ChannelData * channel , MembersFilter filter ) : TWidget ( )
, _rowHeight ( st : : contactsPadding . top ( ) + st : : contactsPhotoSize + st : : contactsPadding . bottom ( ) )
, _newItemHeight ( ( channel - > amCreator ( ) & & ( channel - > count < cMaxGroupCount ( ) | | ! channel - > isPublic ( ) | | filter = = MembersFilterAdmins ) ) ? st : : contactsNewItemHeight : 0 )
, _newItemSel ( false )
, _channel ( channel )
, _filter ( filter )
, _kickText ( lang ( lng_profile_kick ) )
, _time ( 0 )
, _kickWidth ( st : : normalFont - > width ( _kickText ) )
, _sel ( - 1 )
, _kickSel ( - 1 )
, _kickDown ( - 1 )
, _mouseSel ( false )
, _kickConfirm ( 0 )
, _kickRequestId ( 0 )
, _kickBox ( 0 )
, _loading ( true )
, _loadingRequestId ( 0 ) {
connect ( App : : wnd ( ) , SIGNAL ( imageLoaded ( ) ) , this , SLOT ( update ( ) ) ) ;
connect ( App : : main ( ) , SIGNAL ( peerNameChanged ( PeerData * , const PeerData : : Names & , const PeerData : : NameFirstChars & ) ) , this , SLOT ( onPeerNameChanged ( PeerData * , const PeerData : : Names & , const PeerData : : NameFirstChars & ) ) ) ;
2015-09-23 20:43:08 +03:00
connect ( App : : main ( ) , SIGNAL ( peerPhotoChanged ( PeerData * ) ) , this , SLOT ( peerUpdated ( PeerData * ) ) ) ;
refresh ( ) ;
load ( ) ;
}
void MembersInner : : load ( ) {
if ( ! _loadingRequestId ) {
_loadingRequestId = MTP : : send ( MTPchannels_GetParticipants ( _channel - > inputChannel , ( _filter = = MembersFilterRecent ) ? MTP_channelParticipantsRecent ( ) : MTP_channelParticipantsAdmins ( ) , MTP_int ( 0 ) , MTP_int ( cMaxGroupCount ( ) ) ) , rpcDone ( & MembersInner : : membersReceived ) , rpcFail ( & MembersInner : : membersFailed ) ) ;
}
}
void MembersInner : : paintEvent ( QPaintEvent * e ) {
QRect r ( e - > rect ( ) ) ;
Painter p ( this ) ;
_time = unixtime ( ) ;
p . fillRect ( r , st : : white - > b ) ;
2015-10-01 17:05:05 +03:00
int32 yFrom = r . y ( ) - st : : membersPadding . top ( ) , yTo = r . y ( ) + r . height ( ) - st : : membersPadding . top ( ) ;
2015-09-23 20:43:08 +03:00
p . translate ( 0 , st : : membersPadding . top ( ) ) ;
if ( _rows . isEmpty ( ) ) {
p . setFont ( st : : noContactsFont - > f ) ;
p . setPen ( st : : noContactsColor - > p ) ;
p . drawText ( QRect ( 0 , 0 , width ( ) , st : : noContactsHeight ) , lang ( lng_contacts_loading ) , style : : al_center ) ;
} else {
2015-10-11 10:37:24 +02:00
if ( _newItemHeight ) {
p . fillRect ( 0 , 0 , width ( ) , _newItemHeight , ( _newItemSel ? st : : contactsBgOver : st : : white ) - > b ) ;
p . drawSpriteLeft ( st : : contactsNewItemIconPosition . x ( ) , st : : contactsNewItemIconPosition . y ( ) , width ( ) , st : : contactsNewItemIcon ) ;
p . setFont ( st : : contactsNameFont ) ;
p . setPen ( st : : contactsNewItemFg ) ;
p . drawTextLeft ( st : : contactsPadding . left ( ) + st : : contactsPhotoSize + st : : contactsPadding . left ( ) , st : : contactsNewItemTop , width ( ) , lang ( _filter = = MembersFilterAdmins ? lng_channel_add_admins : lng_channel_add_members ) ) ;
yFrom - = _newItemHeight ;
yTo - = _newItemHeight ;
p . translate ( 0 , _newItemHeight ) ;
}
int32 from = floorclamp ( yFrom , _rowHeight , 0 , _rows . size ( ) ) ;
int32 to = ceilclamp ( yTo , _rowHeight , 0 , _rows . size ( ) ) ;
p . translate ( 0 , from * _rowHeight ) ;
2015-10-01 17:05:05 +03:00
for ( ; from < to ; + + from ) {
bool sel = ( from = = _sel ) ;
bool kickSel = ( from = = _kickSel & & ( _kickDown < 0 | | from = = _kickDown ) ) ;
bool kickDown = kickSel & & ( from = = _kickDown ) ;
paintDialog ( p , _rows [ from ] , data ( from ) , sel , kickSel , kickDown ) ;
2015-10-11 10:37:24 +02:00
p . translate ( 0 , _rowHeight ) ;
2015-09-23 20:43:08 +03:00
}
}
}
void MembersInner : : enterEvent ( QEvent * e ) {
setMouseTracking ( true ) ;
}
void MembersInner : : leaveEvent ( QEvent * e ) {
2015-10-11 10:37:24 +02:00
_mouseSel = false ;
2015-09-23 20:43:08 +03:00
setMouseTracking ( false ) ;
if ( _sel > = 0 ) {
2015-10-11 10:37:24 +02:00
clearSel ( ) ;
2015-09-23 20:43:08 +03:00
}
}
void MembersInner : : mouseMoveEvent ( QMouseEvent * e ) {
_mouseSel = true ;
_lastMousePos = e - > globalPos ( ) ;
updateSel ( ) ;
}
void MembersInner : : mousePressEvent ( QMouseEvent * e ) {
_mouseSel = true ;
_lastMousePos = e - > globalPos ( ) ;
updateSel ( ) ;
if ( e - > button ( ) = = Qt : : LeftButton & & _kickSel < 0 ) {
chooseParticipant ( ) ;
}
_kickDown = _kickSel ;
update ( ) ;
}
void MembersInner : : mouseReleaseEvent ( QMouseEvent * e ) {
_mouseSel = true ;
_lastMousePos = e - > globalPos ( ) ;
updateSel ( ) ;
if ( _kickDown > = 0 & & _kickDown = = _kickSel & & ! _kickRequestId ) {
_kickConfirm = _rows . at ( _kickSel ) ;
if ( _kickBox ) _kickBox - > deleteLater ( ) ;
_kickBox = new ConfirmBox ( ( _filter = = MembersFilterRecent ? lng_profile_sure_kick_channel : lng_profile_sure_kick_admin ) ( lt_user , _kickConfirm - > firstName ) ) ;
connect ( _kickBox , SIGNAL ( confirmed ( ) ) , this , SLOT ( onKickConfirm ( ) ) ) ;
connect ( _kickBox , SIGNAL ( destroyed ( QObject * ) ) , this , SLOT ( onKickBoxDestroyed ( QObject * ) ) ) ;
App : : wnd ( ) - > replaceLayer ( _kickBox ) ;
}
_kickDown = - 1 ;
}
void MembersInner : : onKickBoxDestroyed ( QObject * obj ) {
if ( _kickBox = = obj ) {
_kickBox = 0 ;
}
}
void MembersInner : : onKickConfirm ( ) {
if ( _filter = = MembersFilterRecent ) {
_kickRequestId = MTP : : send ( MTPchannels_KickFromChannel ( _channel - > inputChannel , _kickConfirm - > inputUser , MTP_bool ( true ) ) , rpcDone ( & MembersInner : : kickDone ) , rpcFail ( & MembersInner : : kickFail ) ) ;
} else {
_kickRequestId = MTP : : send ( MTPchannels_EditAdmin ( _channel - > inputChannel , _kickConfirm - > inputUser , MTP_channelRoleEmpty ( ) ) , rpcDone ( & MembersInner : : kickAdminDone ) , rpcFail ( & MembersInner : : kickFail ) ) ;
}
}
void MembersInner : : paintDialog ( Painter & p , PeerData * peer , MemberData * data , bool sel , bool kickSel , bool kickDown ) {
UserData * user = peer - > asUser ( ) ;
2015-10-11 10:37:24 +02:00
p . fillRect ( 0 , 0 , width ( ) , _rowHeight , ( sel ? st : : contactsBgOver : st : : white ) - > b ) ;
p . drawPixmapLeft ( st : : contactsPadding . left ( ) , st : : contactsPadding . top ( ) , width ( ) , peer - > photo - > pix ( st : : contactsPhotoSize ) ) ;
2015-09-23 20:43:08 +03:00
2015-10-11 10:37:24 +02:00
p . setPen ( st : : black ) ;
2015-09-23 20:43:08 +03:00
2015-10-11 10:37:24 +02:00
int32 namex = st : : contactsPadding . left ( ) + st : : contactsPhotoSize + st : : contactsPadding . left ( ) ;
int32 namew = width ( ) - namex - st : : contactsPadding . right ( ) - ( data - > canKick ? ( _kickWidth + st : : contactsCheckPosition . x ( ) * 2 ) : 0 ) ;
if ( peer - > isChannel ( ) & & peer - > asChannel ( ) - > isVerified ( ) ) {
namew - = st : : verifiedCheck . pxWidth ( ) + st : : verifiedCheckPos . x ( ) ;
p . drawSpriteLeft ( namex + qMin ( data - > name . maxWidth ( ) , namew ) + st : : verifiedCheckPos . x ( ) , st : : contactsPadding . top ( ) + st : : contactsNameTop + st : : verifiedCheckPos . y ( ) , width ( ) , st : : verifiedCheck ) ;
}
data - > name . drawElided ( p , namex , st : : contactsPadding . top ( ) + st : : contactsNameTop , namew ) ;
2015-09-23 20:43:08 +03:00
if ( data - > canKick ) {
p . setFont ( ( kickSel ? st : : linkOverFont : st : : linkFont ) - > f ) ;
if ( kickDown ) {
p . setPen ( st : : btnDefLink . downColor - > p ) ;
} else {
p . setPen ( st : : btnDefLink . color - > p ) ;
}
2015-10-11 10:37:24 +02:00
p . drawTextRight ( st : : contactsPadding . right ( ) + st : : contactsCheckPosition . x ( ) , st : : contactsPadding . top ( ) + ( st : : contactsPhotoSize - st : : normalFont - > height ) / 2 , width ( ) , _kickText , _kickWidth ) ;
2015-09-23 20:43:08 +03:00
}
2015-10-11 10:37:24 +02:00
p . setFont ( st : : contactsStatusFont - > f ) ;
p . setPen ( sel ? st : : contactsStatusFgOver : st : : contactsStatusFg ) ;
p . drawTextLeft ( namex , st : : contactsPadding . top ( ) + st : : contactsStatusTop , width ( ) , data - > online ) ;
2015-09-23 20:43:08 +03:00
}
void MembersInner : : selectSkip ( int32 dir ) {
_time = unixtime ( ) ;
_mouseSel = false ;
2015-10-11 10:37:24 +02:00
int cur = - 1 ;
if ( _newItemHeight & & _newItemSel ) {
cur = 0 ;
} else if ( _sel > = 0 ) {
cur = _sel + ( _newItemHeight ? 1 : 0 ) ;
}
2015-09-23 20:43:08 +03:00
cur + = dir ;
if ( cur < = 0 ) {
2015-10-11 10:37:24 +02:00
_newItemSel = _newItemHeight ? true : false ;
_sel = ( _newItemSel | | _rows . isEmpty ( ) ) ? - 1 : 0 ;
} else if ( cur > = _rows . size ( ) + ( _newItemHeight ? 1 : 0 ) ) {
2015-09-23 20:43:08 +03:00
_sel = - 1 ;
} else {
2015-10-11 10:37:24 +02:00
_sel = cur - ( _newItemHeight ? 1 : 0 ) ;
2015-09-23 20:43:08 +03:00
}
if ( dir > 0 ) {
if ( _sel < 0 | | _sel > = _rows . size ( ) ) {
_sel = - 1 ;
}
} else {
if ( ! _rows . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
if ( _sel < 0 & & ! _newItemSel ) _sel = _rows . size ( ) - 1 ;
2015-09-23 20:43:08 +03:00
}
}
2015-10-11 10:37:24 +02:00
if ( _newItemSel ) {
emit mustScrollTo ( 0 , _newItemHeight ) ;
} else if ( _sel > = 0 ) {
emit mustScrollTo ( _newItemHeight + _sel * _rowHeight , _newItemHeight + ( _sel + 1 ) * _rowHeight ) ;
2015-09-23 20:43:08 +03:00
}
2015-10-01 17:05:05 +03:00
update ( ) ;
2015-09-23 20:43:08 +03:00
}
void MembersInner : : selectSkipPage ( int32 h , int32 dir ) {
2015-10-11 10:37:24 +02:00
int32 points = h / _rowHeight ;
2015-09-23 20:43:08 +03:00
if ( ! points ) return ;
selectSkip ( points * dir ) ;
}
void MembersInner : : loadProfilePhotos ( int32 yFrom ) {
int32 yTo = yFrom + ( parentWidget ( ) ? parentWidget ( ) - > height ( ) : App : : wnd ( ) - > height ( ) ) * 5 ;
MTP : : clearLoaderPriorities ( ) ;
if ( yTo < 0 ) return ;
if ( yFrom < 0 ) yFrom = 0 ;
if ( ! _rows . isEmpty ( ) ) {
2015-10-11 10:37:24 +02:00
int32 from = ( yFrom - _newItemHeight ) / _rowHeight ;
2015-09-23 20:43:08 +03:00
if ( from < 0 ) from = 0 ;
if ( from < _rows . size ( ) ) {
2015-10-11 10:37:24 +02:00
int32 to = ( ( yTo - _newItemHeight ) / _rowHeight ) + 1 ;
2015-09-23 20:43:08 +03:00
if ( to > _rows . size ( ) ) to = _rows . size ( ) ;
for ( ; from < to ; + + from ) {
_rows [ from ] - > photo - > load ( ) ;
}
}
}
}
void MembersInner : : chooseParticipant ( ) {
2015-10-11 10:37:24 +02:00
if ( _newItemSel ) {
emit addRequested ( ) ;
return ;
}
2015-09-23 20:43:08 +03:00
if ( _sel < 0 | | _sel > = _rows . size ( ) ) return ;
if ( PeerData * peer = _rows [ _sel ] ) {
App : : wnd ( ) - > hideLayer ( ) ;
App : : main ( ) - > showPeerProfile ( peer , ShowAtUnreadMsgId ) ;
}
}
void MembersInner : : refresh ( ) {
if ( _rows . isEmpty ( ) ) {
resize ( width ( ) , st : : membersPadding . top ( ) + st : : noContactsHeight + st : : membersPadding . bottom ( ) ) ;
} else {
2015-10-11 10:37:24 +02:00
resize ( width ( ) , st : : membersPadding . top ( ) + _newItemHeight + _rows . size ( ) * _rowHeight + st : : membersPadding . bottom ( ) ) ;
2015-09-23 20:43:08 +03:00
}
update ( ) ;
}
ChannelData * MembersInner : : channel ( ) const {
return _channel ;
}
MembersFilter MembersInner : : filter ( ) const {
return _filter ;
}
QMap < UserData * , bool > MembersInner : : already ( ) const {
MembersAlreadyIn result ;
for ( int32 i = 0 , l = _rows . size ( ) ; i < l ; + + i ) {
if ( _rows . at ( i ) - > isUser ( ) ) {
result . insert ( _rows . at ( i ) - > asUser ( ) , true ) ;
}
}
return result ;
}
void MembersInner : : clearSel ( ) {
2015-10-03 13:09:09 +03:00
updateSelectedRow ( ) ;
2015-10-11 10:37:24 +02:00
_newItemSel = false ;
2015-09-23 20:43:08 +03:00
_sel = _kickSel = _kickDown = - 1 ;
_lastMousePos = QCursor : : pos ( ) ;
updateSel ( ) ;
}
MembersInner : : MemberData * MembersInner : : data ( int32 index ) {
if ( MemberData * result = _datas . at ( index ) ) {
return result ;
}
MemberData * result = _datas [ index ] = new MemberData ( ) ;
2015-10-11 10:37:24 +02:00
result - > name . setText ( st : : contactsNameFont , _rows [ index ] - > name , _textNameOptions ) ;
2015-09-23 20:43:08 +03:00
result - > online = lng_mediaview_date_time ( lt_date , _dates [ index ] . date ( ) . toString ( qsl ( " dd.MM.yy " ) ) , lt_time , _dates [ index ] . time ( ) . toString ( cTimeFormat ( ) ) ) ;
if ( _filter = = MembersFilterRecent ) {
result - > canKick = ( _channel - > amCreator ( ) | | _channel - > amEditor ( ) | | _channel - > amModerator ( ) ) ? ( _roles [ index ] = = MemberRoleNone ) : false ;
} else if ( _filter = = MembersFilterAdmins ) {
result - > canKick = _channel - > amCreator ( ) ? ( _roles [ index ] = = MemberRoleEditor | | _roles [ index ] = = MemberRoleModerator ) : false ;
} else {
result - > canKick = false ;
}
return result ;
}
void MembersInner : : clear ( ) {
for ( int32 i = 0 , l = _datas . size ( ) ; i < l ; + + i ) {
delete _datas . at ( i ) ;
}
_datas . clear ( ) ;
_rows . clear ( ) ;
_dates . clear ( ) ;
_roles . clear ( ) ;
if ( _kickBox ) _kickBox - > deleteLater ( ) ;
clearSel ( ) ;
}
MembersInner : : ~ MembersInner ( ) {
clear ( ) ;
}
void MembersInner : : updateSel ( ) {
2015-10-11 10:37:24 +02:00
if ( ! _mouseSel ) return ;
2015-09-23 20:43:08 +03:00
QPoint p ( mapFromGlobal ( _lastMousePos ) ) ;
p . setY ( p . y ( ) - st : : membersPadding . top ( ) ) ;
bool in = parentWidget ( ) - > rect ( ) . contains ( parentWidget ( ) - > mapFromGlobal ( _lastMousePos ) ) ;
2015-10-11 10:37:24 +02:00
bool newItemSel = ( in & & p . y ( ) > = 0 & & p . y ( ) < _newItemHeight ) ;
int32 newSel = ( in & & ! newItemSel & & p . y ( ) > = _newItemHeight & & p . y ( ) < _newItemHeight + _rows . size ( ) * _rowHeight ) ? ( ( p . y ( ) - _newItemHeight ) / _rowHeight ) : - 1 ;
2015-09-23 20:43:08 +03:00
int32 newKickSel = newSel ;
2015-10-11 10:37:24 +02:00
if ( newSel > = 0 & & ( ! data ( newSel ) - > canKick | | ! QRect ( width ( ) - _kickWidth - st : : contactsPadding . right ( ) - st : : contactsCheckPosition . x ( ) , _newItemHeight + newSel * _rowHeight + st : : contactsPadding . top ( ) + ( st : : contactsPhotoSize - st : : normalFont - > height ) / 2 , _kickWidth , st : : normalFont - > height ) . contains ( p ) ) ) {
2015-09-23 20:43:08 +03:00
newKickSel = - 1 ;
}
2015-10-11 10:37:24 +02:00
if ( newSel ! = _sel | | newKickSel ! = _kickSel | | newItemSel ! = _newItemSel ) {
2015-10-01 17:05:05 +03:00
updateSelectedRow ( ) ;
2015-10-11 10:37:24 +02:00
_newItemSel = newItemSel ;
2015-09-23 20:43:08 +03:00
_sel = newSel ;
_kickSel = newKickSel ;
2015-10-01 17:05:05 +03:00
updateSelectedRow ( ) ;
2015-09-23 20:43:08 +03:00
setCursor ( _kickSel > = 0 ? style : : cur_pointer : style : : cur_default ) ;
}
}
void MembersInner : : peerUpdated ( PeerData * peer ) {
2015-10-01 17:05:05 +03:00
update ( ) ;
}
void MembersInner : : updateSelectedRow ( ) {
2015-10-11 10:37:24 +02:00
if ( _newItemSel ) {
update ( 0 , st : : membersPadding . top ( ) , width ( ) , _newItemHeight ) ;
}
2015-10-01 17:05:05 +03:00
if ( _sel > = 0 ) {
2015-10-11 10:37:24 +02:00
update ( 0 , st : : membersPadding . top ( ) + _newItemHeight + _sel * _rowHeight , width ( ) , _rowHeight ) ;
2015-10-01 17:05:05 +03:00
}
2015-09-23 20:43:08 +03:00
}
void MembersInner : : onPeerNameChanged ( PeerData * peer , const PeerData : : Names & oldNames , const PeerData : : NameFirstChars & oldChars ) {
for ( int32 i = 0 , l = _rows . size ( ) ; i < l ; + + i ) {
if ( _rows . at ( i ) = = peer ) {
if ( _datas . at ( i ) ) {
2015-10-11 10:37:24 +02:00
_datas . at ( i ) - > name . setText ( st : : contactsNameFont , peer - > name , _textNameOptions ) ;
update ( 0 , st : : membersPadding . top ( ) + i * _rowHeight , width ( ) , _rowHeight ) ;
2015-09-23 20:43:08 +03:00
} else {
break ;
}
}
}
}
void MembersInner : : membersReceived ( const MTPchannels_ChannelParticipants & result , mtpRequestId req ) {
clear ( ) ;
_loadingRequestId = 0 ;
if ( result . type ( ) = = mtpc_channels_channelParticipants ) {
const MTPDchannels_channelParticipants & d ( result . c_channels_channelParticipants ( ) ) ;
const QVector < MTPChannelParticipant > & v ( d . vparticipants . c_vector ( ) . v ) ;
_rows . reserve ( v . size ( ) ) ;
_datas . reserve ( v . size ( ) ) ;
_dates . reserve ( v . size ( ) ) ;
_roles . reserve ( v . size ( ) ) ;
2015-09-25 11:17:52 +03:00
if ( _filter = = MembersFilterRecent & & _channel - > count < d . vcount . v ) {
2015-09-23 20:43:08 +03:00
_channel - > count = d . vcount . v ;
if ( App : : main ( ) ) emit App : : main ( ) - > peerUpdated ( _channel ) ;
2015-09-25 11:17:52 +03:00
} else if ( _filter = = MembersFilterAdmins & & _channel - > adminsCount < d . vcount . v ) {
2015-09-23 20:43:08 +03:00
_channel - > adminsCount = d . vcount . v ;
if ( App : : main ( ) ) emit App : : main ( ) - > peerUpdated ( _channel ) ;
}
App : : feedUsers ( d . vusers ) ;
for ( QVector < MTPChannelParticipant > : : const_iterator i = v . cbegin ( ) , e = v . cend ( ) ; i ! = e ; + + i ) {
int32 userId = 0 , addedTime = 0 ;
MemberRole role = MemberRoleNone ;
switch ( i - > type ( ) ) {
case mtpc_channelParticipant :
userId = i - > c_channelParticipant ( ) . vuser_id . v ;
addedTime = i - > c_channelParticipant ( ) . vdate . v ;
break ;
case mtpc_channelParticipantSelf :
role = MemberRoleSelf ;
userId = i - > c_channelParticipantSelf ( ) . vuser_id . v ;
addedTime = i - > c_channelParticipantSelf ( ) . vdate . v ;
break ;
case mtpc_channelParticipantModerator :
role = MemberRoleModerator ;
userId = i - > c_channelParticipantModerator ( ) . vuser_id . v ;
addedTime = i - > c_channelParticipantModerator ( ) . vdate . v ;
break ;
case mtpc_channelParticipantEditor :
role = MemberRoleEditor ;
userId = i - > c_channelParticipantEditor ( ) . vuser_id . v ;
addedTime = i - > c_channelParticipantEditor ( ) . vdate . v ;
break ;
case mtpc_channelParticipantKicked :
userId = i - > c_channelParticipantKicked ( ) . vuser_id . v ;
addedTime = i - > c_channelParticipantKicked ( ) . vdate . v ;
role = MemberRoleKicked ;
break ;
case mtpc_channelParticipantCreator :
userId = i - > c_channelParticipantCreator ( ) . vuser_id . v ;
addedTime = _channel - > date ;
role = MemberRoleCreator ;
break ;
}
if ( UserData * user = App : : userLoaded ( userId ) ) {
_rows . push_back ( user ) ;
_dates . push_back ( date ( addedTime ) ) ;
_roles . push_back ( role ) ;
_datas . push_back ( 0 ) ;
}
}
}
if ( _rows . isEmpty ( ) ) {
_rows . push_back ( App : : self ( ) ) ;
_dates . push_back ( date ( MTP_int ( _channel - > date ) ) ) ;
_roles . push_back ( MemberRoleSelf ) ;
_datas . push_back ( 0 ) ;
}
clearSel ( ) ;
_loading = false ;
refresh ( ) ;
emit loaded ( ) ;
}
bool MembersInner : : membersFailed ( const RPCError & error , mtpRequestId req ) {
if ( mtpIsFlood ( error ) ) return false ;
App : : wnd ( ) - > hideLayer ( ) ;
return true ;
}
void MembersInner : : kickDone ( const MTPUpdates & result , mtpRequestId req ) {
App : : main ( ) - > sentUpdatesReceived ( result ) ;
if ( _kickRequestId ! = req ) return ;
removeKicked ( ) ;
if ( _kickBox ) _kickBox - > onClose ( ) ;
}
void MembersInner : : kickAdminDone ( const MTPBool & result , mtpRequestId req ) {
if ( _kickRequestId ! = req ) return ;
removeKicked ( ) ;
if ( _kickBox ) _kickBox - > onClose ( ) ;
}
bool MembersInner : : kickFail ( const RPCError & error , mtpRequestId req ) {
if ( mtpIsFlood ( error ) ) return false ;
if ( _kickBox ) _kickBox - > onClose ( ) ;
load ( ) ;
return true ;
}
void MembersInner : : removeKicked ( ) {
_kickRequestId = 0 ;
int32 index = _rows . indexOf ( _kickConfirm ) ;
if ( index > = 0 ) {
_rows . removeAt ( index ) ;
delete _datas . at ( index ) ;
_datas . removeAt ( index ) ;
_dates . removeAt ( index ) ;
_roles . removeAt ( index ) ;
clearSel ( ) ;
if ( _filter = = MembersFilterRecent & & _channel - > count > 1 ) {
- - _channel - > count ;
if ( App : : main ( ) ) emit App : : main ( ) - > peerUpdated ( _channel ) ;
} else if ( _filter = = MembersFilterAdmins & & _channel - > adminsCount > 1 ) {
- - _channel - > adminsCount ;
if ( App : : main ( ) ) emit App : : main ( ) - > peerUpdated ( _channel ) ;
}
}
_kickConfirm = 0 ;
}
2015-10-11 10:37:24 +02:00
MembersBox : : MembersBox ( ChannelData * channel , MembersFilter filter ) : ItemListBox ( st : : boxScroll )
, _inner ( channel , filter )
, _addBox ( 0 ) {
ItemListBox : : init ( & _inner ) ;
2015-09-23 20:43:08 +03:00
2015-10-11 10:37:24 +02:00
connect ( & _inner , SIGNAL ( addRequested ( ) ) , this , SLOT ( onAdd ( ) ) ) ;
2015-09-23 20:43:08 +03:00
connect ( & _scroll , SIGNAL ( scrolled ( ) ) , & _inner , SLOT ( updateSel ( ) ) ) ;
connect ( & _scroll , SIGNAL ( scrolled ( ) ) , this , SLOT ( onScroll ( ) ) ) ;
connect ( & _inner , SIGNAL ( mustScrollTo ( int , int ) ) , & _scroll , SLOT ( scrollToY ( int , int ) ) ) ;
connect ( & _inner , SIGNAL ( loaded ( ) ) , this , SLOT ( onLoaded ( ) ) ) ;
2015-09-25 10:47:32 +03:00
connect ( & _loadTimer , SIGNAL ( timeout ( ) ) , & _inner , SLOT ( load ( ) ) ) ;
2015-09-23 20:43:08 +03:00
prepare ( ) ;
}
void MembersBox : : keyPressEvent ( QKeyEvent * e ) {
if ( e - > key ( ) = = Qt : : Key_Down ) {
_inner . selectSkip ( 1 ) ;
} else if ( e - > key ( ) = = Qt : : Key_Up ) {
_inner . selectSkip ( - 1 ) ;
} else if ( e - > key ( ) = = Qt : : Key_PageDown ) {
_inner . selectSkipPage ( _scroll . height ( ) , 1 ) ;
} else if ( e - > key ( ) = = Qt : : Key_PageUp ) {
_inner . selectSkipPage ( _scroll . height ( ) , - 1 ) ;
} else {
ItemListBox : : keyPressEvent ( e ) ;
}
}
void MembersBox : : paintEvent ( QPaintEvent * e ) {
Painter p ( this ) ;
if ( paint ( p ) ) return ;
QString title ( lang ( _inner . filter ( ) = = MembersFilterRecent ? lng_channel_members : lng_channel_admins ) ) ;
2015-10-12 23:31:05 +02:00
paintTitle ( p , title ) ;
2015-09-23 20:43:08 +03:00
}
void MembersBox : : resizeEvent ( QResizeEvent * e ) {
ItemListBox : : resizeEvent ( e ) ;
_inner . resize ( width ( ) , _inner . height ( ) ) ;
}
void MembersBox : : onScroll ( ) {
_inner . loadProfilePhotos ( _scroll . scrollTop ( ) ) ;
}
void MembersBox : : onAdd ( ) {
if ( _inner . filter ( ) = = MembersFilterRecent & & _inner . channel ( ) - > count > = cMaxGroupCount ( ) ) {
App : : wnd ( ) - > replaceLayer ( new MaxInviteBox ( _inner . channel ( ) - > invitationUrl ) ) ;
return ;
}
ContactsBox * box = new ContactsBox ( _inner . channel ( ) , _inner . filter ( ) , _inner . already ( ) ) ;
if ( _inner . filter ( ) = = MembersFilterRecent ) {
2015-10-03 13:09:09 +03:00
App : : wnd ( ) - > showLayer ( box ) ;
2015-09-23 20:43:08 +03:00
} else {
_addBox = box ;
connect ( _addBox , SIGNAL ( adminAdded ( ) ) , this , SLOT ( onAdminAdded ( ) ) ) ;
App : : wnd ( ) - > replaceLayer ( _addBox ) ;
}
}
void MembersBox : : onAdminAdded ( ) {
if ( ! _addBox ) return ;
_addBox - > onClose ( ) ;
_addBox = 0 ;
2015-09-25 10:47:32 +03:00
_loadTimer . start ( ReloadChannelMembersTimeout ) ;
2015-09-23 20:43:08 +03:00
}
void MembersBox : : showDone ( ) {
2015-10-03 13:09:09 +03:00
_inner . clearSel ( ) ;
2015-09-23 20:43:08 +03:00
setFocus ( ) ;
}