mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
New profile blocks started. Info block fully ready.
All block widgets added (currently empty). About text and phone number PeerUpdateFlag added for observers.
This commit is contained in:
parent
a06a989f97
commit
41c8df029a
48 changed files with 1342 additions and 165 deletions
|
@ -405,12 +405,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
"lng_profile_actions_section" = "Actions";
|
||||
"lng_profile_bot_settings" = "Settings";
|
||||
"lng_profile_bot_help" = "Help";
|
||||
"lng_profile_invite_link_section" = "Invite link";
|
||||
"lng_profile_create_public_link" = "Create public link";
|
||||
"lng_profile_edit_public_link" = "Edit public link";
|
||||
"lng_profile_participants_section" = "Members";
|
||||
"lng_profile_info" = "Contact info";
|
||||
"lng_profile_group_info" = "Group info";
|
||||
"lng_profile_channel_info" = "Channel info";
|
||||
"lng_profile_info_section" = "Info";
|
||||
"lng_profile_mobile_number" = "Mobile:";
|
||||
"lng_profile_username" = "Username:";
|
||||
"lng_profile_link" = "Link:";
|
||||
"lng_profile_add_contact" = "Add Contact";
|
||||
"lng_profile_edit_contact" = "Edit";
|
||||
"lng_profile_enable_notifications" = "Notifications";
|
||||
|
@ -912,6 +914,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
// Not used
|
||||
|
||||
"lng_topbar_info" = "Info";
|
||||
"lng_profile_group_info" = "Group info";
|
||||
"lng_profile_channel_info" = "Channel info";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
|
|||
} break;
|
||||
}
|
||||
}
|
||||
channel->about = qs(f.vabout);
|
||||
channel->setAbout(qs(f.vabout));
|
||||
int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0;
|
||||
if (newCount != channel->count) {
|
||||
if (channel->isMegagroup() && !channel->mgInfo->lastParticipants.isEmpty()) {
|
||||
|
@ -343,7 +343,7 @@ void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestI
|
|||
peer->asUser()->setBotInfoVersion(-1);
|
||||
}
|
||||
peer->asUser()->blocked = d.is_blocked() ? UserIsBlocked : UserIsNotBlocked;
|
||||
peer->asUser()->about = d.has_about() ? qs(d.vabout) : QString();
|
||||
peer->asUser()->setAbout(d.has_about() ? qs(d.vabout) : QString());
|
||||
|
||||
if (req) {
|
||||
QMap<PeerData*, mtpRequestId>::iterator i = _fullPeerRequests.find(peer);
|
||||
|
|
|
@ -428,7 +428,10 @@ namespace {
|
|||
}
|
||||
}
|
||||
if (d.is_deleted()) {
|
||||
data->setPhone(QString());
|
||||
if (!data->phone().isEmpty()) {
|
||||
data->setPhone(QString());
|
||||
update.flags |= UpdateFlag::UserPhoneChanged;
|
||||
}
|
||||
data->setNameDelayed(lang(lng_deleted), QString(), QString(), QString());
|
||||
data->setPhoto(MTP_userProfilePhotoEmpty());
|
||||
data->access = UserNoAccess;
|
||||
|
@ -440,12 +443,14 @@ namespace {
|
|||
QString fname = (!minimal || noLocalName) ? (d.has_first_name() ? textOneLine(qs(d.vfirst_name)) : QString()) : data->firstName;
|
||||
QString lname = (!minimal || noLocalName) ? (d.has_last_name() ? textOneLine(qs(d.vlast_name)) : QString()) : data->lastName;
|
||||
|
||||
QString phone = minimal ? data->phone : (d.has_phone() ? qs(d.vphone) : QString());
|
||||
QString phone = minimal ? data->phone() : (d.has_phone() ? qs(d.vphone) : QString());
|
||||
QString uname = minimal ? data->username : (d.has_username() ? textOneLine(qs(d.vusername)) : QString());
|
||||
|
||||
bool phoneChanged = (data->phone != phone);
|
||||
if (phoneChanged) data->setPhone(phone);
|
||||
|
||||
bool phoneChanged = (data->phone() != phone);
|
||||
if (phoneChanged) {
|
||||
data->setPhone(phone);
|
||||
update.flags |= UpdateFlag::UserPhoneChanged;
|
||||
}
|
||||
bool nameChanged = (data->firstName != fname) || (data->lastName != lname);
|
||||
|
||||
bool showPhone = !isServiceUser(data->id) && !d.is_self() && !d.is_contact() && !d.is_mutual_contact();
|
||||
|
@ -480,7 +485,7 @@ namespace {
|
|||
} else {
|
||||
data->setBotInfoVersion(-1);
|
||||
}
|
||||
data->contact = (d.is_contact() || d.is_mutual_contact()) ? 1 : (data->phone.isEmpty() ? -1 : 0);
|
||||
data->contact = (d.is_contact() || d.is_mutual_contact()) ? 1 : (data->phone().isEmpty() ? -1 : 0);
|
||||
if (data->contact == 1 && cReportSpamStatuses().value(data->id, dbiprsHidden) != dbiprsHidden) {
|
||||
cRefReportSpamStatuses().insert(data->id, dbiprsHidden);
|
||||
Local::writeReportSpamStatuses();
|
||||
|
@ -522,7 +527,7 @@ namespace {
|
|||
case mtpc_userStatusOnline: data->onlineTill = status->c_userStatusOnline().vexpires.v; break;
|
||||
}
|
||||
|
||||
if (data->contact < 0 && !data->phone.isEmpty() && peerToUser(data->id) != MTP::authedId()) {
|
||||
if (data->contact < 0 && !data->phone().isEmpty() && peerToUser(data->id) != MTP::authedId()) {
|
||||
data->contact = 0;
|
||||
}
|
||||
if (App::main()) {
|
||||
|
@ -1259,7 +1264,7 @@ namespace {
|
|||
break;
|
||||
}
|
||||
if (user->contact < 1) {
|
||||
if (user->contact < 0 && !user->phone.isEmpty() && peerToUser(user->id) != MTP::authedId()) {
|
||||
if (user->contact < 0 && !user->phone().isEmpty() && peerToUser(user->id) != MTP::authedId()) {
|
||||
user->contact = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1276,7 +1281,7 @@ namespace {
|
|||
bool showPhone = !isServiceUser(user->id) && !user->isSelf() && !user->contact;
|
||||
bool showPhoneChanged = !isServiceUser(user->id) && !user->isSelf() && ((showPhone && !wasShowPhone) || (!showPhone && wasShowPhone));
|
||||
if (showPhoneChanged) {
|
||||
user->setNameDelayed(textOneLine(user->firstName), textOneLine(user->lastName), showPhone ? App::formatPhone(user->phone) : QString(), textOneLine(user->username));
|
||||
user->setNameDelayed(textOneLine(user->firstName), textOneLine(user->lastName), showPhone ? App::formatPhone(user->phone()) : QString(), textOneLine(user->username));
|
||||
}
|
||||
markPeerUpdated(user);
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
AboutBox::AboutBox() : AbstractBox(st::aboutWidth)
|
||||
, _version(this, lng_about_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + (cAlphaVersion() ? " alpha" : "") + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())), st::aboutVersionLink)
|
||||
, _text1(this, lang(lng_about_text_1), st::aboutLabel, st::aboutTextStyle)
|
||||
, _text2(this, lang(lng_about_text_2), st::aboutLabel, st::aboutTextStyle)
|
||||
, _text3(this, QString(), st::aboutLabel, st::aboutTextStyle)
|
||||
, _text1(this, lang(lng_about_text_1), FlatLabel::InitType::Rich, st::aboutLabel, st::aboutTextStyle)
|
||||
, _text2(this, lang(lng_about_text_2), FlatLabel::InitType::Rich, st::aboutLabel, st::aboutTextStyle)
|
||||
, _text3(this,st::aboutLabel, st::aboutTextStyle)
|
||||
, _done(this, lang(lng_close), st::defaultBoxButton) {
|
||||
_text3.setRichText(lng_about_text_3(lt_faq_open, qsl("[a href=\"%1\"]").arg(telegramFaqLink()), lt_faq_close, qsl("[/a]")));
|
||||
|
||||
|
|
|
@ -33,16 +33,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "observer_peer.h"
|
||||
|
||||
AddContactBox::AddContactBox(QString fname, QString lname, QString phone) : AbstractBox(st::boxWidth)
|
||||
, _user(0)
|
||||
, _save(this, lang(lng_add_contact), st::defaultBoxButton)
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||
, _retry(this, lang(lng_try_other_contact), st::defaultBoxButton)
|
||||
, _first(this, st::defaultInputField, lang(lng_signup_firstname), fname)
|
||||
, _last(this, st::defaultInputField, lang(lng_signup_lastname), lname)
|
||||
, _phone(this, st::defaultInputField, lang(lng_contact_phone), phone)
|
||||
, _invertOrder(langFirstNameGoesSecond())
|
||||
, _contactId(0)
|
||||
, _addRequest(0) {
|
||||
, _invertOrder(langFirstNameGoesSecond()) {
|
||||
if (!phone.isEmpty()) {
|
||||
_phone.setDisabled(true);
|
||||
}
|
||||
|
@ -57,10 +54,8 @@ AddContactBox::AddContactBox(UserData *user) : AbstractBox(st::boxWidth)
|
|||
, _retry(this, lang(lng_try_other_contact), st::defaultBoxButton)
|
||||
, _first(this, st::defaultInputField, lang(lng_signup_firstname), user->firstName)
|
||||
, _last(this, st::defaultInputField, lang(lng_signup_lastname), user->lastName)
|
||||
, _phone(this, st::defaultInputField, lang(lng_contact_phone), user->phone)
|
||||
, _invertOrder(langFirstNameGoesSecond())
|
||||
, _contactId(0)
|
||||
, _addRequest(0) {
|
||||
, _phone(this, st::defaultInputField, lang(lng_contact_phone), user->phone())
|
||||
, _invertOrder(langFirstNameGoesSecond()) {
|
||||
_phone.setDisabled(true);
|
||||
initBox();
|
||||
}
|
||||
|
@ -191,7 +186,7 @@ void AddContactBox::onSave() {
|
|||
_sentName = firstName;
|
||||
if (_user) {
|
||||
_contactId = rand_value<uint64>();
|
||||
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_user->phone), MTP_string(firstName), MTP_string(lastName)));
|
||||
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_user->phone()), MTP_string(firstName), MTP_string(lastName)));
|
||||
_addRequest = MTP::send(MTPcontacts_ImportContacts(MTP_vector<MTPInputContact>(v), MTP_bool(false)), rpcDone(&AddContactBox::onSaveUserDone), rpcFail(&AddContactBox::onSaveUserFail));
|
||||
} else {
|
||||
_contactId = rand_value<uint64>();
|
||||
|
@ -1181,7 +1176,7 @@ EditChannelBox::EditChannelBox(ChannelData *channel) : AbstractBox()
|
|||
, _save(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||
, _title(this, st::defaultInputField, lang(lng_dlg_new_channel_name), _channel->name)
|
||||
, _description(this, st::newGroupDescription, lang(lng_create_group_description), _channel->about)
|
||||
, _description(this, st::newGroupDescription, lang(lng_create_group_description), _channel->about())
|
||||
, _sign(this, lang(lng_edit_sign_messages), channel->addsSignature())
|
||||
, _publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), st::defaultBoxLinkButton)
|
||||
, _saveTitleRequestId(0)
|
||||
|
@ -1322,7 +1317,7 @@ void EditChannelBox::onPublicLink() {
|
|||
}
|
||||
|
||||
void EditChannelBox::saveDescription() {
|
||||
if (_sentDescription == _channel->about) {
|
||||
if (_sentDescription == _channel->about()) {
|
||||
saveSign();
|
||||
} else {
|
||||
_saveDescriptionRequestId = MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||
|
@ -1357,9 +1352,11 @@ bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) {
|
|||
} else if (req == _saveDescriptionRequestId) {
|
||||
_saveDescriptionRequestId = 0;
|
||||
if (err == qstr("CHAT_ABOUT_NOT_MODIFIED")) {
|
||||
_channel->about = _sentDescription;
|
||||
if (App::api()) {
|
||||
emit App::api()->fullPeerUpdated(_channel);
|
||||
if (_channel->setAbout(_sentDescription)) {
|
||||
if (App::api()) {
|
||||
emit App::api()->fullPeerUpdated(_channel);
|
||||
}
|
||||
Notify::peerUpdatedSendDelayed();
|
||||
}
|
||||
saveSign();
|
||||
return true;
|
||||
|
@ -1386,9 +1383,11 @@ void EditChannelBox::onSaveTitleDone(const MTPUpdates &updates) {
|
|||
|
||||
void EditChannelBox::onSaveDescriptionDone(const MTPBool &result) {
|
||||
_saveDescriptionRequestId = 0;
|
||||
_channel->about = _sentDescription;
|
||||
if (App::api()) {
|
||||
emit App::api()->fullPeerUpdated(_channel);
|
||||
if (_channel->setAbout(_sentDescription)) {
|
||||
if (App::api()) {
|
||||
emit App::api()->fullPeerUpdated(_channel);
|
||||
}
|
||||
Notify::peerUpdatedSendDelayed();
|
||||
}
|
||||
saveSign();
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
|
||||
void initBox();
|
||||
|
||||
UserData *_user;
|
||||
UserData *_user = nullptr;
|
||||
QString _boxTitle;
|
||||
|
||||
BoxButton _save, _cancel, _retry;
|
||||
|
@ -66,9 +66,9 @@ private:
|
|||
|
||||
bool _invertOrder;
|
||||
|
||||
uint64 _contactId;
|
||||
uint64 _contactId = 0;
|
||||
|
||||
mtpRequestId _addRequest;
|
||||
mtpRequestId _addRequest = 0;
|
||||
QString _sentName;
|
||||
};
|
||||
|
||||
|
|
|
@ -381,11 +381,10 @@ void ConvertToSupergroupBox::resizeEvent(QResizeEvent *e) {
|
|||
PinMessageBox::PinMessageBox(ChannelData *channel, MsgId msgId) : AbstractBox(st::boxWidth)
|
||||
, _channel(channel)
|
||||
, _msgId(msgId)
|
||||
, _text(this, lang(lng_pinned_pin_sure), st::boxLabel)
|
||||
, _text(this, lang(lng_pinned_pin_sure), FlatLabel::InitType::Simple, st::boxLabel)
|
||||
, _notify(this, lang(lng_pinned_notify), true)
|
||||
, _pin(this, lang(lng_pinned_pin), st::defaultBoxButton)
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||
, _requestId(0) {
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||
_text.resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
|
||||
setMaxHeight(st::boxPadding.top() + _text.height() + st::boxMediumSkip + _notify.height() + st::boxPadding.bottom() + st::boxButtonPadding.top() + _pin.height() + st::boxButtonPadding.bottom());
|
||||
|
||||
|
@ -441,7 +440,7 @@ RichDeleteMessageBox::RichDeleteMessageBox(ChannelData *channel, UserData *from,
|
|||
, _channel(channel)
|
||||
, _from(from)
|
||||
, _msgId(msgId)
|
||||
, _text(this, lang(lng_selected_delete_sure_this), st::boxLabel)
|
||||
, _text(this, lang(lng_selected_delete_sure_this), FlatLabel::InitType::Simple, st::boxLabel)
|
||||
, _banUser(this, lang(lng_ban_user), false)
|
||||
, _reportSpam(this, lang(lng_report_spam), false)
|
||||
, _deleteAll(this, lang(lng_delete_all_from), false)
|
||||
|
|
|
@ -217,7 +217,7 @@ private:
|
|||
|
||||
BoxButton _pin, _cancel;
|
||||
|
||||
mtpRequestId _requestId;
|
||||
mtpRequestId _requestId = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ enum ExpandLinksMode {
|
|||
ExpandLinksNone,
|
||||
ExpandLinksShortened,
|
||||
ExpandLinksAll,
|
||||
ExpandLinksUrlOnly, // For custom urls leaves only url instead of text.
|
||||
};
|
||||
|
||||
class ClickHandlerHost {
|
||||
|
|
|
@ -110,15 +110,22 @@ QString HiddenUrlClickHandler::getExpandedLinkText(ExpandLinksMode mode, const Q
|
|||
QString result;
|
||||
if (mode == ExpandLinksAll) {
|
||||
result = textPart.toString() + qsl(" (") + url() + ')';
|
||||
} else if (mode == ExpandLinksUrlOnly) {
|
||||
result = url();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
TextWithEntities HiddenUrlClickHandler::getExpandedLinkTextWithEntities(ExpandLinksMode mode, int entityOffset, const QStringRef &textPart) const {
|
||||
TextWithEntities result;
|
||||
result.entities.push_back({ EntityInTextCustomUrl, entityOffset, textPart.size(), url() });
|
||||
if (mode == ExpandLinksAll) {
|
||||
result.text = textPart.toString() + qsl(" (") + url() + ')';
|
||||
if (mode == ExpandLinksUrlOnly) {
|
||||
result.text = url();
|
||||
result.entities.push_back({ EntityInTextUrl, entityOffset, result.text.size() });
|
||||
} else {
|
||||
result.entities.push_back({ EntityInTextCustomUrl, entityOffset, textPart.size(), url() });
|
||||
if (mode == ExpandLinksAll) {
|
||||
result.text = textPart.toString() + qsl(" (") + url() + ')';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -174,9 +181,19 @@ TextWithEntities HashtagClickHandler::getExpandedLinkTextWithEntities(ExpandLink
|
|||
return simpleTextWithEntity({ EntityInTextHashtag, entityOffset, textPart.size() });
|
||||
}
|
||||
|
||||
PeerData *BotCommandClickHandler::_peer = nullptr;
|
||||
UserData *BotCommandClickHandler::_bot = nullptr;
|
||||
void BotCommandClickHandler::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
if (PeerData *peer = Ui::getPeerForMouseAction()) {
|
||||
if (auto peer = peerForCommand()) {
|
||||
if (auto bot = peer->isUser() ? peer->asUser() : botForCommand()) {
|
||||
Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
|
||||
App::sendBotCommand(peer, bot, _cmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto peer = Ui::getPeerForMouseAction()) { // old way
|
||||
UserData *bot = peer->isUser() ? peer->asUser() : nullptr;
|
||||
if (auto item = App::hoveredLinkItem()) {
|
||||
if (!bot) {
|
||||
|
|
|
@ -193,6 +193,8 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class PeerData;
|
||||
class UserData;
|
||||
class BotCommandClickHandler : public TextClickHandler {
|
||||
public:
|
||||
BotCommandClickHandler(const QString &cmd) : _cmd(cmd) {
|
||||
|
@ -204,14 +206,30 @@ public:
|
|||
return _cmd;
|
||||
}
|
||||
|
||||
static void setPeerForCommand(PeerData *peer) {
|
||||
_peer = peer;
|
||||
}
|
||||
static void setBotForCommand(UserData *bot) {
|
||||
_bot = bot;
|
||||
}
|
||||
|
||||
TextWithEntities getExpandedLinkTextWithEntities(ExpandLinksMode mode, int entityOffset, const QStringRef &textPart) const override;
|
||||
|
||||
protected:
|
||||
QString url() const override {
|
||||
return _cmd;
|
||||
}
|
||||
static PeerData *peerForCommand() {
|
||||
return _peer;
|
||||
}
|
||||
static UserData *botForCommand() {
|
||||
return _bot;
|
||||
}
|
||||
|
||||
private:
|
||||
QString _cmd;
|
||||
|
||||
static PeerData *_peer;
|
||||
static UserData *_bot;
|
||||
|
||||
};
|
||||
|
|
|
@ -5034,7 +5034,7 @@ void HistoryWidget::onBroadcastSilentChange() {
|
|||
}
|
||||
|
||||
void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
|
||||
auto phone = contact->phone;
|
||||
auto phone = contact->phone();
|
||||
if (phone.isEmpty()) phone = App::phoneFromSharedContact(peerToUser(contact->id));
|
||||
if (!contact || phone.isEmpty()) return;
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ IntroPhone::IntroPhone(IntroWidget *parent) : IntroStep(parent)
|
|||
, country(this, st::introCountry)
|
||||
, phone(this, st::inpIntroPhone)
|
||||
, code(this, st::inpIntroCountryCode)
|
||||
, _signup(this, lng_phone_notreg(lt_signup_start, textcmdStartLink(1), lt_signup_end, textcmdStopLink()), st::introErrLabel, st::introErrLabelTextStyle)
|
||||
, _signup(this, lng_phone_notreg(lt_signup_start, textcmdStartLink(1), lt_signup_end, textcmdStopLink()), FlatLabel::InitType::Rich, st::introErrLabel, st::introErrLabelTextStyle)
|
||||
, _showSignup(false)
|
||||
, sentRequest(0) {
|
||||
setVisible(false);
|
||||
|
|
|
@ -27,7 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "langloaderplain.h"
|
||||
|
||||
IntroStart::IntroStart(IntroWidget *parent) : IntroStep(parent)
|
||||
, _intro(this, lang(lng_intro), st::introLabel, st::introLabelTextStyle)
|
||||
, _intro(this, lang(lng_intro), FlatLabel::InitType::Rich, st::introLabel, st::introLabelTextStyle)
|
||||
, _changeLang(this, QString())
|
||||
, _next(this, lang(lng_start_msgs), st::btnIntroNext) {
|
||||
_changeLang.hide();
|
||||
|
|
|
@ -3407,7 +3407,7 @@ namespace Local {
|
|||
UserData *user = peer->asUser();
|
||||
|
||||
// first + last + phone + username + access
|
||||
result += Serialize::stringSize(user->firstName) + Serialize::stringSize(user->lastName) + Serialize::stringSize(user->phone) + Serialize::stringSize(user->username) + sizeof(quint64);
|
||||
result += Serialize::stringSize(user->firstName) + Serialize::stringSize(user->lastName) + Serialize::stringSize(user->phone()) + Serialize::stringSize(user->username) + sizeof(quint64);
|
||||
|
||||
// flags
|
||||
if (AppVersion >= 9012) {
|
||||
|
@ -3436,7 +3436,7 @@ namespace Local {
|
|||
if (peer->isUser()) {
|
||||
UserData *user = peer->asUser();
|
||||
|
||||
stream << user->firstName << user->lastName << user->phone << user->username << quint64(user->access);
|
||||
stream << user->firstName << user->lastName << user->phone() << user->username << quint64(user->access);
|
||||
if (AppVersion >= 9012) {
|
||||
stream << qint32(user->flags);
|
||||
}
|
||||
|
@ -3490,6 +3490,7 @@ namespace Local {
|
|||
QString pname = (showPhone && !phone.isEmpty()) ? App::formatPhone(phone) : QString();
|
||||
|
||||
if (!wasLoaded) {
|
||||
user->setPhone(phone);
|
||||
user->setNameDelayed(first, last, pname, username);
|
||||
|
||||
user->access = access;
|
||||
|
|
|
@ -4389,9 +4389,16 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
|||
case mtpc_updateUserPhone: {
|
||||
auto &d(update.c_updateUserPhone());
|
||||
if (auto user = App::userLoaded(d.vuser_id.v)) {
|
||||
user->setPhone(qs(d.vphone));
|
||||
user->setNameDelayed(user->firstName, user->lastName, (user->contact || isServiceUser(user->id) || user->isSelf() || user->phone.isEmpty()) ? QString() : App::formatPhone(user->phone), user->username);
|
||||
App::markPeerUpdated(user);
|
||||
auto newPhone = qs(d.vphone);
|
||||
if (newPhone != user->phone()) {
|
||||
user->setPhone(newPhone);
|
||||
user->setNameDelayed(user->firstName, user->lastName, (user->contact || isServiceUser(user->id) || user->isSelf() || user->phone().isEmpty()) ? QString() : App::formatPhone(user->phone()), user->username);
|
||||
App::markPeerUpdated(user);
|
||||
|
||||
Notify::PeerUpdate update(user);
|
||||
update.flags |= Notify::PeerUpdateFlag::UserPhoneChanged;
|
||||
Notify::peerUpdatedDelayed(update);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
|
|
|
@ -33,9 +33,11 @@ enum class PeerUpdateFlag {
|
|||
NameChanged = 0x00000001U,
|
||||
UsernameChanged = 0x00000002U,
|
||||
PhotoChanged = 0x00000004U,
|
||||
AboutChanged = 0x00000008U,
|
||||
|
||||
UserCanShareContact = 0x00010000U,
|
||||
UserIsContact = 0x00020000U,
|
||||
UserPhoneChanged = 0x00040000U,
|
||||
|
||||
ChatCanEdit = 0x00010000U,
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ profileFixedBarButton: flatButton(topBarButton) {
|
|||
|
||||
profileMarginTop: 13px;
|
||||
profilePhotoSize: 112px;
|
||||
profilePhotoLeft: 35px;
|
||||
profilePhotoLeftMin: 18px;
|
||||
profilePhotoLeftMax: 45px;
|
||||
profilePhotoDuration: 500;
|
||||
profileNameLeft: 26px;
|
||||
profileNameTop: 9px;
|
||||
|
@ -106,7 +107,28 @@ profileDividerFill: icon {
|
|||
};
|
||||
|
||||
profileBlocksTop: 7px;
|
||||
profileBlocksBottom: 20px;
|
||||
profileBlockLeftMin: 8px;
|
||||
profileBlockLeftMax: 25px;
|
||||
profileBlockNarrowWidthMin: 220px;
|
||||
profileBlockWideWidthMin: 300px;
|
||||
profileBlockWideWidthMax: 340px;
|
||||
profileBlockMarginTop: 21px;
|
||||
profileBlockTitleFont: semiboldFont;
|
||||
profileBlockMarginRight: 10px;
|
||||
profileBlockMarginBottom: 4px;
|
||||
profileBlockTitleHeight: 22px;
|
||||
profileBlockTitleFont: font(14px semibold);
|
||||
profileBlockTitleFg: black;
|
||||
profileBlockTitlePosition: point(16px, profileBlockMarginTop);
|
||||
profileBlockTitlePosition: point(24px, -7px);
|
||||
profileBlockLabel: flatLabel(labelDefFlat) {
|
||||
textFg: windowSubTextFg;
|
||||
}
|
||||
profileBlockTextPart: flatLabel(labelDefFlat) {
|
||||
width: 180px;
|
||||
margin: margins(5px, 5px, 5px, 5px);
|
||||
}
|
||||
profileBlockOneLineTextPart: flatLabel(profileBlockTextPart) {
|
||||
width: 0px; // No need to set minWidth in one-line text.
|
||||
maxHeight: 20px;
|
||||
}
|
||||
profileBlockOneLineSkip: 9px;
|
||||
|
|
40
Telegram/SourceFiles/profile/profile_actions_widget.cpp
Normal file
40
Telegram/SourceFiles/profile/profile_actions_widget.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_actions_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
ActionsWidget::ActionsWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_actions_section))
|
||||
{
|
||||
show();
|
||||
}
|
||||
|
||||
int ActionsWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
} // namespace Profile
|
37
Telegram/SourceFiles/profile/profile_actions_widget.h
Normal file
37
Telegram/SourceFiles/profile/profile_actions_widget.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class ActionsWidget : public BlockWidget {
|
||||
public:
|
||||
ActionsWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
|
@ -34,12 +34,18 @@ void BlockWidget::resizeToWidth(int newWidth) {
|
|||
resize(newWidth, resizeGetHeight(newWidth));
|
||||
}
|
||||
|
||||
int BlockWidget::contentTop() const {
|
||||
return st::profileBlockMarginTop + st::profileBlockTitleHeight;
|
||||
}
|
||||
|
||||
void BlockWidget::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
p.setFont(st::profileBlockTitleFont);
|
||||
p.setPen(st::profileBlockTitleFg);
|
||||
p.drawText(st::profileBlockTitlePosition, _title);
|
||||
int titleLeft = st::profileBlockTitlePosition.x();
|
||||
int titleTop = st::profileBlockMarginTop + st::profileBlockTitlePosition.y();
|
||||
p.drawTextLeft(titleLeft, titleTop, width(), _title);
|
||||
|
||||
paintContents(p);
|
||||
}
|
||||
|
|
|
@ -35,14 +35,25 @@ public:
|
|||
virtual void setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
}
|
||||
|
||||
signals:
|
||||
void heightUpdated();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
virtual void paintContents(Painter &p) {
|
||||
}
|
||||
|
||||
// Where does the block content start (after the title).
|
||||
int contentTop() const;
|
||||
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
virtual int resizeGetHeight(int newWidth) = 0;
|
||||
|
||||
void contentSizeUpdated() {
|
||||
resizeToWidth(width());
|
||||
emit heightUpdated();
|
||||
}
|
||||
|
||||
PeerData *peer() const {
|
||||
return _peer;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent)
|
|||
, _peerChannel(peer->asChannel())
|
||||
, _peerMegagroup(peer->isMegagroup() ? _peerChannel : nullptr)
|
||||
, _userpicButton(this, peer)
|
||||
, _name(this, QString(), st::profileNameLabel) {
|
||||
, _name(this, st::profileNameLabel) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
setAcceptDrops(true);
|
||||
|
||||
|
@ -109,20 +109,23 @@ void CoverWidget::onPhotoShow() {
|
|||
}
|
||||
}
|
||||
|
||||
int CoverWidget::countPhotoLeft(int newWidth) const {
|
||||
int result = st::profilePhotoLeftMin;
|
||||
result += (newWidth - st::wndMinWidth) / 2;
|
||||
return qMin(result, st::profilePhotoLeftMax);
|
||||
}
|
||||
|
||||
void CoverWidget::resizeToWidth(int newWidth) {
|
||||
int newHeight = 0;
|
||||
|
||||
newHeight += st::profileMarginTop;
|
||||
_userpicButton->moveToLeft(st::profilePhotoLeft, newHeight);
|
||||
|
||||
_photoLeft = countPhotoLeft(newWidth);
|
||||
_userpicButton->moveToLeft(_photoLeft, newHeight);
|
||||
|
||||
refreshNameGeometry(newWidth);
|
||||
|
||||
int infoLeft = _userpicButton->x() + _userpicButton->width();
|
||||
int nameLeft = infoLeft + st::profileNameLeft - st::profileNameLabel.margin.left();
|
||||
int nameTop = _userpicButton->y() + st::profileNameTop - st::profileNameLabel.margin.top();
|
||||
_name.moveToLeft(nameLeft, nameTop);
|
||||
int nameWidth = newWidth - infoLeft - st::profileNameLeft - st::profileButtonSkip;
|
||||
nameWidth += st::profileNameLabel.margin.left() + st::profileNameLabel.margin.right();
|
||||
_name.resizeToWidth(nameWidth);
|
||||
|
||||
_statusPosition = QPoint(infoLeft + st::profileStatusLeft, _userpicButton->y() + st::profileStatusTop);
|
||||
|
||||
moveAndToggleButtons(newWidth);
|
||||
|
@ -140,29 +143,43 @@ void CoverWidget::resizeToWidth(int newWidth) {
|
|||
update();
|
||||
}
|
||||
|
||||
void CoverWidget::refreshNameGeometry(int newWidth) {
|
||||
int infoLeft = _userpicButton->x() + _userpicButton->width();
|
||||
int nameLeft = infoLeft + st::profileNameLeft - st::profileNameLabel.margin.left();
|
||||
int nameTop = _userpicButton->y() + st::profileNameTop - st::profileNameLabel.margin.top();
|
||||
int nameWidth = newWidth - infoLeft - st::profileNameLeft - st::profileButtonSkip;
|
||||
int marginsAdd = st::profileNameLabel.margin.left() + st::profileNameLabel.margin.right();
|
||||
_name.resizeToWidth(qMin(nameWidth, _name.naturalWidth()) + marginsAdd);
|
||||
_name.moveToLeft(nameLeft, nameTop);
|
||||
}
|
||||
|
||||
// A more generic solution would be allowing an optional icon button
|
||||
// for each text button. But currently we use only one, so it is done easily:
|
||||
// There can be primary + secondary + icon buttons. If primary + secondary fit,
|
||||
// then icon is hidden, otherwise secondary is hidden and icon is shown.
|
||||
void CoverWidget::moveAndToggleButtons(int newWiddth) {
|
||||
bool showNextButton = true;
|
||||
int buttonLeft = st::profilePhotoLeft + _userpicButton->width() + st::profileButtonLeft;
|
||||
int buttonLeft = _userpicButton->x() + _userpicButton->width() + st::profileButtonLeft;
|
||||
int buttonsRight = newWiddth - st::profileButtonSkip;
|
||||
for (int i = 0, count = _buttons.size(); i < count; ++i) {
|
||||
auto button = _buttons.at(i);
|
||||
button->moveToLeft(buttonLeft, st::profileButtonTop);
|
||||
if (i == 1) {
|
||||
// If second button is not fitting.
|
||||
if (buttonLeft + button->width() > buttonsRight) {
|
||||
button->hide();
|
||||
auto &button = _buttons.at(i);
|
||||
button.widget->moveToLeft(buttonLeft, st::profileButtonTop);
|
||||
if (button.replacement) {
|
||||
button.replacement->moveToLeft(buttonLeft, st::profileButtonTop);
|
||||
if (buttonLeft + button.widget->width() > buttonsRight) {
|
||||
button.widget->hide();
|
||||
button.replacement->show();
|
||||
buttonLeft += button.replacement->width() + st::profileButtonSkip;
|
||||
} else {
|
||||
button->show();
|
||||
buttonLeft += button->width() + st::profileButtonSkip;
|
||||
showNextButton = false;
|
||||
button.widget->show();
|
||||
button.replacement->hide();
|
||||
buttonLeft += button.widget->width() + st::profileButtonSkip;
|
||||
}
|
||||
} else if (i == 1 && (buttonLeft + button.widget->width() > buttonsRight)) {
|
||||
// If second button is not fitting.
|
||||
button.widget->hide();
|
||||
} else {
|
||||
button->setVisible(showNextButton);
|
||||
buttonLeft += button->width() + st::profileButtonSkip;
|
||||
button.widget->show();
|
||||
buttonLeft += button.widget->width() + st::profileButtonSkip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +189,7 @@ void CoverWidget::showFinished() {
|
|||
}
|
||||
|
||||
bool CoverWidget::shareContactButtonShown() const {
|
||||
return _peerUser && (_buttons.size() > 1) && !(_buttons.at(1)->isHidden());
|
||||
return _peerUser && (_buttons.size() > 1) && !(_buttons.at(1).widget->isHidden());
|
||||
}
|
||||
|
||||
void CoverWidget::paintEvent(QPaintEvent *e) {
|
||||
|
@ -195,8 +212,7 @@ void CoverWidget::resizeDropArea() {
|
|||
|
||||
void CoverWidget::dropAreaHidden(CoverDropArea *dropArea) {
|
||||
if (_dropArea == dropArea) {
|
||||
_dropArea->deleteLater();
|
||||
_dropArea = nullptr;
|
||||
_dropArea.destroyDelayed();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,7 +330,7 @@ void CoverWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
|||
|
||||
void CoverWidget::refreshNameText() {
|
||||
_name.setText(App::peerName(_peer));
|
||||
update();
|
||||
refreshNameGeometry(width());
|
||||
}
|
||||
|
||||
void CoverWidget::refreshStatusText() {
|
||||
|
@ -394,8 +410,7 @@ void CoverWidget::setUserButtons() {
|
|||
void CoverWidget::setChatButtons() {
|
||||
if (_peerChat->canEdit()) {
|
||||
addButton(lang(lng_profile_set_group_photo), SLOT(onSetPhoto()));
|
||||
addButton(lang(lng_profile_add_participant), SLOT(onAddMember()));
|
||||
addButton(st::profileAddMemberButton, SLOT(onAddMember()));
|
||||
addButton(lang(lng_profile_add_participant), SLOT(onAddMember()), &st::profileAddMemberButton);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,8 +419,7 @@ void CoverWidget::setMegagroupButtons() {
|
|||
addButton(lang(lng_profile_set_group_photo), SLOT(onSetPhoto()));
|
||||
}
|
||||
if (_peerMegagroup->canAddParticipants()) {
|
||||
addButton(lang(lng_profile_add_participant), SLOT(onAddMember()));
|
||||
addButton(st::profileAddMemberButton, SLOT(onAddMember()));
|
||||
addButton(lang(lng_profile_add_participant), SLOT(onAddMember()), &st::profileAddMemberButton);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,21 +436,24 @@ void CoverWidget::setChannelButtons() {
|
|||
void CoverWidget::clearButtons() {
|
||||
auto buttons = createAndSwap(_buttons);
|
||||
for_const (auto button, buttons) {
|
||||
delete button;
|
||||
delete button.widget;
|
||||
delete button.replacement;
|
||||
}
|
||||
}
|
||||
|
||||
void CoverWidget::addButton(const QString &text, const char *slot) {
|
||||
void CoverWidget::addButton(const QString &text, const char *slot, const style::BoxButton *replacementStyle) {
|
||||
auto &buttonStyle = _buttons.isEmpty() ? st::profilePrimaryButton : st::profileSecondaryButton;
|
||||
_buttons.push_back(new Ui::RoundButton(this, text, buttonStyle));
|
||||
connect(_buttons.back(), SIGNAL(clicked()), this, slot);
|
||||
_buttons.back()->show();
|
||||
}
|
||||
auto button = new Ui::RoundButton(this, text, buttonStyle);
|
||||
connect(button, SIGNAL(clicked()), this, slot);
|
||||
button->show();
|
||||
|
||||
void CoverWidget::addButton(const style::BoxButton &buttonStyle, const char *slot) {
|
||||
_buttons.push_back(new Ui::RoundButton(this, QString(), buttonStyle));
|
||||
connect(_buttons.back(), SIGNAL(clicked()), this, slot);
|
||||
_buttons.back()->hide();
|
||||
auto replacement = replacementStyle ? new Ui::RoundButton(this, QString(), *replacementStyle) : nullptr;
|
||||
if (replacement) {
|
||||
connect(replacement, SIGNAL(clicked()), this, slot);
|
||||
replacement->hide();
|
||||
}
|
||||
|
||||
_buttons.push_back({ button, replacement });
|
||||
}
|
||||
|
||||
void CoverWidget::onSendMessage() {
|
||||
|
|
|
@ -75,6 +75,10 @@ private:
|
|||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
void notifyFileQueryUpdated(const FileDialog::QueryUpdate &update);
|
||||
|
||||
// Counts userpic button left offset for a new widget width.
|
||||
int countPhotoLeft(int newWidth) const;
|
||||
|
||||
void refreshNameGeometry(int newWidth);
|
||||
void moveAndToggleButtons(int newWiddth);
|
||||
void refreshNameText();
|
||||
void refreshStatusText();
|
||||
|
@ -87,8 +91,7 @@ private:
|
|||
void setChannelButtons();
|
||||
|
||||
void clearButtons();
|
||||
void addButton(const QString &text, const char *slot);
|
||||
void addButton(const style::BoxButton &buttonStyle, const char *slot);
|
||||
void addButton(const QString &text, const char *slot, const style::BoxButton *replacementStyle = nullptr);
|
||||
|
||||
void paintDivider(Painter &p);
|
||||
|
||||
|
@ -112,8 +115,13 @@ private:
|
|||
QPoint _statusPosition;
|
||||
QString _statusText;
|
||||
|
||||
QList<Ui::RoundButton*> _buttons;
|
||||
struct Button {
|
||||
Ui::RoundButton *widget;
|
||||
Ui::RoundButton *replacement;
|
||||
};
|
||||
QList<Button> _buttons;
|
||||
|
||||
int _photoLeft = 0; // Caching countPhotoLeft() result.
|
||||
int _dividerTop = 0;
|
||||
|
||||
FileDialog::QueryId _setPhotoFileQueryId = 0;
|
||||
|
|
|
@ -177,7 +177,7 @@ void FixedBar::onEditGroup() {
|
|||
void FixedBar::onAddContact() {
|
||||
auto firstName = _peerUser->firstName;
|
||||
auto lastName = _peerUser->lastName;
|
||||
auto phone = _peerUser->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(_peer->id)) : _peerUser->phone;
|
||||
auto phone = _peerUser->phone().isEmpty() ? App::phoneFromSharedContact(peerToUser(_peer->id)) : _peerUser->phone();
|
||||
Ui::showLayer(new AddContactBox(firstName, lastName, phone));
|
||||
}
|
||||
|
||||
|
@ -223,8 +223,8 @@ void FixedBar::resizeToWidth(int newWidth) {
|
|||
i->button->moveToLeft(buttonLeft, 0);
|
||||
}
|
||||
|
||||
_backButton->moveToLeft(0, 0);
|
||||
_backButton->resizeToWidth(newWidth);
|
||||
_backButton->moveToLeft(0, 0);
|
||||
newHeight += _backButton->height();
|
||||
|
||||
resize(newWidth, newHeight);
|
||||
|
|
217
Telegram/SourceFiles/profile/profile_info_widget.cpp
Normal file
217
Telegram/SourceFiles/profile/profile_info_widget.cpp
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_info_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/flatlabel.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "observer_peer.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
InfoWidget::InfoWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_info_section)) {
|
||||
auto observeEvents = Notify::PeerUpdateFlag::AboutChanged
|
||||
| Notify::PeerUpdateFlag::UsernameChanged
|
||||
| Notify::PeerUpdateFlag::UserPhoneChanged
|
||||
| Notify::PeerUpdateFlag::UserCanShareContact;
|
||||
Notify::registerPeerObserver(observeEvents, this, &InfoWidget::notifyPeerUpdated);
|
||||
|
||||
refreshLabels();
|
||||
}
|
||||
|
||||
void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
if (update.peer != peer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (update.flags & Notify::PeerUpdateFlag::AboutChanged) {
|
||||
refreshAbout();
|
||||
}
|
||||
if (update.flags & Notify::PeerUpdateFlag::UsernameChanged) {
|
||||
refreshUsername();
|
||||
refreshChannelLink();
|
||||
}
|
||||
if (update.flags & (Notify::PeerUpdateFlag::UserPhoneChanged | Notify::PeerUpdateFlag::UserCanShareContact)) {
|
||||
refreshMobileNumber();
|
||||
}
|
||||
refreshVisibility();
|
||||
|
||||
contentSizeUpdated();
|
||||
}
|
||||
|
||||
int InfoWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
int marginLeft = st::profileBlockTextPart.margin.left();
|
||||
int marginRight = st::profileBlockTextPart.margin.right();
|
||||
int left = st::profileBlockTitlePosition.x();
|
||||
if (_about) {
|
||||
int textWidth = _about->naturalWidth();
|
||||
int availableWidth = newWidth - left - st::profileBlockMarginRight;
|
||||
int maxWidth = st::msgMaxWidth;
|
||||
accumulate_min(textWidth, availableWidth);
|
||||
accumulate_min(textWidth, st::msgMaxWidth);
|
||||
_about->resizeToWidth(textWidth + marginLeft + marginRight);
|
||||
_about->moveToLeft(left - marginLeft, newHeight - st::profileBlockTextPart.margin.top());
|
||||
newHeight += _about->height();
|
||||
}
|
||||
|
||||
auto moveLabeledText = [&newHeight, left, newWidth, marginLeft, marginRight](FlatLabel *label, FlatLabel *text, FlatLabel *shortText) {
|
||||
if (!label) return;
|
||||
|
||||
label->moveToLeft(left, newHeight);
|
||||
int textLeft = left + label->width() + st::normalFont->spacew;
|
||||
int textWidth = text->naturalWidth();
|
||||
int availableWidth = newWidth - textLeft - st::profileBlockMarginRight;
|
||||
bool doesNotFit = (textWidth > availableWidth);
|
||||
accumulate_min(textWidth, availableWidth);
|
||||
accumulate_min(textWidth, st::msgMaxWidth);
|
||||
text->resizeToWidth(textWidth + marginLeft + marginRight);
|
||||
text->moveToLeft(textLeft - marginLeft, newHeight - st::profileBlockOneLineTextPart.margin.top());
|
||||
if (shortText) {
|
||||
shortText->resizeToWidth(textWidth + marginLeft + marginRight);
|
||||
shortText->moveToLeft(textLeft - marginLeft, newHeight - st::profileBlockOneLineTextPart.margin.top());
|
||||
if (doesNotFit) {
|
||||
shortText->show();
|
||||
text->hide();
|
||||
} else {
|
||||
shortText->hide();
|
||||
text->show();
|
||||
}
|
||||
}
|
||||
newHeight += label->height() + st::profileBlockOneLineSkip;
|
||||
};
|
||||
moveLabeledText(_channelLinkLabel, _channelLink, _channelLinkShort);
|
||||
moveLabeledText(_mobileNumberLabel, _mobileNumber, nullptr);
|
||||
moveLabeledText(_usernameLabel, _username, nullptr);
|
||||
|
||||
newHeight += st::profileBlockMarginBottom;
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
void InfoWidget::leaveEvent(QEvent *e) {
|
||||
BotCommandClickHandler::setPeerForCommand(nullptr);
|
||||
BotCommandClickHandler::setBotForCommand(nullptr);
|
||||
}
|
||||
|
||||
void InfoWidget::refreshLabels() {
|
||||
refreshAbout();
|
||||
refreshMobileNumber();
|
||||
refreshUsername();
|
||||
refreshChannelLink();
|
||||
|
||||
refreshVisibility();
|
||||
}
|
||||
|
||||
void InfoWidget::refreshVisibility() {
|
||||
setVisible(_about || _mobileNumber || _username || _channelLink);
|
||||
}
|
||||
|
||||
void InfoWidget::refreshAbout() {
|
||||
auto getAboutText = [this]() -> QString {
|
||||
if (auto user = peer()->asUser()) {
|
||||
return user->about();
|
||||
} else if (auto channel = peer()->asChannel()) {
|
||||
return channel->about();
|
||||
}
|
||||
return QString();
|
||||
};
|
||||
|
||||
_about.destroy();
|
||||
auto aboutText = getAboutText();
|
||||
if (!aboutText.isEmpty()) {
|
||||
_about = new FlatLabel(this, QString(), FlatLabel::InitType::Simple, st::profileBlockTextPart);
|
||||
_about->show();
|
||||
|
||||
EntitiesInText aboutEntities;
|
||||
textParseEntities(aboutText, TextParseLinks | TextParseMentions | TextParseHashtags | TextParseBotCommands, &aboutEntities);
|
||||
_about->setMarkedText({ aboutText, aboutEntities });
|
||||
_about->setSelectable(true);
|
||||
_about->setClickHandlerHook(func(this, &InfoWidget::aboutClickHandlerHook));
|
||||
}
|
||||
}
|
||||
|
||||
bool InfoWidget::aboutClickHandlerHook(const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
||||
BotCommandClickHandler::setPeerForCommand(peer());
|
||||
return true;
|
||||
}
|
||||
|
||||
void InfoWidget::refreshMobileNumber() {
|
||||
TextWithEntities phoneText;
|
||||
if (auto user = peer()->asUser()) {
|
||||
if (!user->phone().isEmpty()) {
|
||||
phoneText.text = App::formatPhone(user->phone());
|
||||
} else {
|
||||
phoneText.text = App::phoneFromSharedContact(peerToUser(user->id));
|
||||
}
|
||||
}
|
||||
setLabeledText(&_mobileNumberLabel, lang(lng_profile_mobile_number), &_mobileNumber, phoneText, lang(lng_profile_copy_phone));
|
||||
}
|
||||
|
||||
void InfoWidget::refreshUsername() {
|
||||
TextWithEntities usernameText;
|
||||
if (auto user = peer()->asUser()) {
|
||||
if (!user->username.isEmpty()) {
|
||||
usernameText.text = '@' + user->username;
|
||||
}
|
||||
}
|
||||
setLabeledText(&_usernameLabel, lang(lng_profile_username), &_username, usernameText, lang(lng_context_copy_mention));
|
||||
}
|
||||
|
||||
void InfoWidget::refreshChannelLink() {
|
||||
TextWithEntities channelLinkText;
|
||||
TextWithEntities channelLinkTextShort;
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
if (!channel->username.isEmpty()) {
|
||||
channelLinkText.text = qsl("https://telegram.me/") + channel->username;
|
||||
channelLinkText.entities.push_back(EntityInText(EntityInTextUrl, 0, channelLinkText.text.size()));
|
||||
channelLinkTextShort.text = qsl("telegram.me/") + channel->username;
|
||||
channelLinkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, channelLinkTextShort.text.size(), qsl("https://telegram.me/") + channel->username));
|
||||
}
|
||||
}
|
||||
setLabeledText(nullptr, lang(lng_profile_link), &_channelLink, channelLinkText, QString());
|
||||
setLabeledText(&_channelLinkLabel, lang(lng_profile_link), &_channelLinkShort, channelLinkTextShort, QString());
|
||||
if (_channelLinkShort) {
|
||||
_channelLinkShort->setExpandLinksMode(ExpandLinksUrlOnly);
|
||||
}
|
||||
}
|
||||
|
||||
void InfoWidget::setLabeledText(ChildWidget<FlatLabel> *labelWidget, const QString &label,
|
||||
ChildWidget<FlatLabel> *textWidget, const TextWithEntities &textWithEntities, const QString ©Text) {
|
||||
if (labelWidget) labelWidget->destroy();
|
||||
textWidget->destroy();
|
||||
if (textWithEntities.text.isEmpty()) return;
|
||||
|
||||
if (labelWidget) {
|
||||
*labelWidget = new FlatLabel(this, label, FlatLabel::InitType::Simple, st::profileBlockLabel);
|
||||
(*labelWidget)->show();
|
||||
}
|
||||
*textWidget = new FlatLabel(this, QString(), FlatLabel::InitType::Simple, st::profileBlockOneLineTextPart);
|
||||
(*textWidget)->show();
|
||||
(*textWidget)->setMarkedText(textWithEntities);
|
||||
(*textWidget)->setContextCopyText(copyText);
|
||||
(*textWidget)->setSelectable(true);
|
||||
(*textWidget)->setDoubleClickSelectsParagraph(true);
|
||||
}
|
||||
|
||||
} // namespace Profile
|
72
Telegram/SourceFiles/profile/profile_info_widget.h
Normal file
72
Telegram/SourceFiles/profile/profile_info_widget.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
#include "core/observer.h"
|
||||
|
||||
class FlatLabel;
|
||||
|
||||
namespace Notify {
|
||||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class InfoWidget : public BlockWidget, public Notify::Observer {
|
||||
public:
|
||||
InfoWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
void leaveEvent(QEvent *e) override;
|
||||
|
||||
private:
|
||||
// Observed notifications.
|
||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
|
||||
void refreshLabels();
|
||||
void refreshAbout();
|
||||
void refreshMobileNumber();
|
||||
void refreshUsername();
|
||||
void refreshChannelLink();
|
||||
void refreshVisibility();
|
||||
|
||||
bool aboutClickHandlerHook(const ClickHandlerPtr &handler, Qt::MouseButton button);
|
||||
|
||||
// labelWidget may be nullptr.
|
||||
void setLabeledText(ChildWidget<FlatLabel> *labelWidget, const QString &label,
|
||||
ChildWidget<FlatLabel> *textWidget, const TextWithEntities &textWithEntities, const QString ©Text);
|
||||
|
||||
ChildWidget<FlatLabel> _about = { nullptr };
|
||||
ChildWidget<FlatLabel> _channelLinkLabel = { nullptr };
|
||||
ChildWidget<FlatLabel> _channelLink = { nullptr };
|
||||
ChildWidget<FlatLabel> _channelLinkShort = { nullptr };
|
||||
ChildWidget<FlatLabel> _mobileNumberLabel = { nullptr };
|
||||
ChildWidget<FlatLabel> _mobileNumber = { nullptr };
|
||||
ChildWidget<FlatLabel> _usernameLabel = { nullptr };
|
||||
ChildWidget<FlatLabel> _username = { nullptr };
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
|
@ -23,6 +23,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "styles/style_profile.h"
|
||||
#include "profile/profile_cover.h"
|
||||
#include "profile/profile_info_widget.h"
|
||||
#include "profile/profile_settings_widget.h"
|
||||
#include "profile/profile_invite_link_widget.h"
|
||||
#include "profile/profile_shared_media_widget.h"
|
||||
#include "profile/profile_actions_widget.h"
|
||||
#include "profile/profile_members_widget.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
namespace Profile {
|
||||
|
@ -31,6 +37,33 @@ InnerWidget::InnerWidget(QWidget *parent, PeerData *peer) : TWidget(parent)
|
|||
, _peer(peer)
|
||||
, _cover(this, peer) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
createBlocks();
|
||||
}
|
||||
|
||||
void InnerWidget::createBlocks() {
|
||||
auto user = _peer->asUser();
|
||||
auto chat = _peer->asChat();
|
||||
auto channel = _peer->asChannel();
|
||||
auto megagroup = _peer->isMegagroup() ? channel : nullptr;
|
||||
if (user || channel || megagroup) {
|
||||
_blocks.push_back({ new InfoWidget(this, _peer), BlockSide::Right });
|
||||
}
|
||||
_blocks.push_back({ new SettingsWidget(this, _peer), BlockSide::Right });
|
||||
if (chat || channel || megagroup) {
|
||||
_blocks.push_back({ new InviteLinkWidget(this, _peer), BlockSide::Right });
|
||||
}
|
||||
_blocks.push_back({ new SharedMediaWidget(this, _peer), BlockSide::Right });
|
||||
_blocks.push_back({ new ActionsWidget(this, _peer), BlockSide::Right });
|
||||
if (channel && !megagroup) {
|
||||
_blocks.push_back({ new ChannelMembersWidget(this, _peer), BlockSide::Right });
|
||||
}
|
||||
if (chat || megagroup) {
|
||||
_blocks.push_back({ new MembersWidget(this, _peer), BlockSide::Left });
|
||||
}
|
||||
for_const (auto &blockData, _blocks) {
|
||||
connect(blockData.block, SIGNAL(heightUpdated()), this, SLOT(onBlockHeightUpdated()));
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::resizeToWidth(int newWidth, int minHeight) {
|
||||
|
@ -45,7 +78,7 @@ void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
|||
|
||||
int notDisplayedAtBottom = height() - _visibleBottom;
|
||||
if (notDisplayedAtBottom > 0) {
|
||||
// decreaseAdditionalHeight(notDisplayedAtBottom); // testing
|
||||
decreaseAdditionalHeight(notDisplayedAtBottom);
|
||||
}
|
||||
|
||||
//loadProfilePhotos(_visibleTop);
|
||||
|
@ -72,6 +105,16 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
Painter p(this);
|
||||
|
||||
p.fillRect(e->rect(), st::profileBg);
|
||||
|
||||
if (_mode == Mode::TwoColumn) {
|
||||
int leftHeight = countBlocksHeight(BlockSide::Left);
|
||||
int rightHeight = countBlocksHeight(BlockSide::Right);
|
||||
int minHeight = qMin(leftHeight, rightHeight);
|
||||
|
||||
int shadowLeft = _blocksLeft + _leftColumnWidth + _columnDivider;
|
||||
int shadowTop = _blocksTop + st::profileBlockMarginTop;
|
||||
p.fillRect(rtlrect(shadowLeft, shadowTop, st::lineWidth, minHeight - st::profileBlockMarginTop, width()), st::shadowColor);
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::keyPressEvent(QKeyEvent *e) {
|
||||
|
@ -80,11 +123,134 @@ void InnerWidget::keyPressEvent(QKeyEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
int InnerWidget::countBlocksHeight(BlockSide countSide) const {
|
||||
int result = 0;
|
||||
for_const (auto &blockData, _blocks) {
|
||||
if (blockData.side != countSide || blockData.block->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result += blockData.block->height();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int InnerWidget::countBlocksLeft(int newWidth) const {
|
||||
int result = st::profileBlockLeftMin;
|
||||
result += (newWidth - st::wndMinWidth) / 2;
|
||||
return qMin(result, st::profileBlockLeftMax);
|
||||
}
|
||||
|
||||
InnerWidget::Mode InnerWidget::countBlocksMode(int newWidth) const {
|
||||
bool hasLeftWidget = false, hasRightWidget = false;
|
||||
for_const (auto &blockData, _blocks) {
|
||||
if (!blockData.block->isHidden()) {
|
||||
if (blockData.side == BlockSide::Left) {
|
||||
hasLeftWidget = true;
|
||||
} else {
|
||||
hasRightWidget = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasLeftWidget || !hasRightWidget) {
|
||||
return Mode::OneColumn;
|
||||
}
|
||||
|
||||
int availWidth = newWidth - _blocksLeft;
|
||||
if (availWidth >= st::profileBlockWideWidthMin + _columnDivider + st::profileBlockNarrowWidthMin) {
|
||||
return Mode::TwoColumn;
|
||||
}
|
||||
return Mode::OneColumn;
|
||||
}
|
||||
|
||||
int InnerWidget::countLeftColumnWidth(int newWidth) const {
|
||||
int result = st::profileBlockWideWidthMin;
|
||||
|
||||
int availWidth = newWidth - _blocksLeft;
|
||||
int additionalWidth = (availWidth - st::profileBlockWideWidthMin - _columnDivider - st::profileBlockNarrowWidthMin);
|
||||
if (additionalWidth > 0) {
|
||||
result += (additionalWidth / 2);
|
||||
accumulate_min(result, st::profileBlockWideWidthMax);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void InnerWidget::refreshBlocksPositions() {
|
||||
auto layoutBlocks = [this](BlockSide layoutSide, int left) {
|
||||
int top = _blocksTop;
|
||||
for_const (auto &blockData, _blocks) {
|
||||
if (_mode == Mode::TwoColumn && blockData.side != layoutSide) {
|
||||
continue;
|
||||
}
|
||||
if (blockData.block->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
blockData.block->moveToLeft(left, top);
|
||||
top += blockData.block->height();
|
||||
}
|
||||
};
|
||||
layoutBlocks(BlockSide::Left, _blocksLeft);
|
||||
if (_mode == Mode::TwoColumn) {
|
||||
layoutBlocks(BlockSide::Right, _blocksLeft + _leftColumnWidth + _columnDivider);
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::resizeBlocks(int newWidth) {
|
||||
for_const (auto &blockData, _blocks) {
|
||||
int blockWidth = newWidth - _blocksLeft;
|
||||
if (_mode == Mode::OneColumn) {
|
||||
blockWidth -= _blocksLeft;
|
||||
} else {
|
||||
if (blockData.side == BlockSide::Left) {
|
||||
blockWidth = _leftColumnWidth;
|
||||
} else {
|
||||
blockWidth -= _leftColumnWidth + _columnDivider;
|
||||
}
|
||||
}
|
||||
blockData.block->resizeToWidth(blockWidth);
|
||||
}
|
||||
}
|
||||
|
||||
int InnerWidget::resizeGetHeight(int newWidth) {
|
||||
_cover->resizeToWidth(newWidth);
|
||||
|
||||
_blocksTop = _cover->y() + _cover->height() + st::profileBlocksTop;
|
||||
_blocksLeft = countBlocksLeft(newWidth);
|
||||
_columnDivider = _blocksLeft;
|
||||
_mode = countBlocksMode(newWidth);
|
||||
_leftColumnWidth = countLeftColumnWidth(newWidth);
|
||||
resizeBlocks(newWidth);
|
||||
|
||||
refreshBlocksPositions();
|
||||
|
||||
update();
|
||||
return countHeight();
|
||||
}
|
||||
|
||||
int InnerWidget::countHeight() const {
|
||||
int newHeight = _cover->height();
|
||||
int leftHeight = countBlocksHeight(BlockSide::Left);
|
||||
int rightHeight = countBlocksHeight(BlockSide::Right);
|
||||
|
||||
int blocksHeight = (_mode == Mode::OneColumn) ? (leftHeight + rightHeight) : qMax(leftHeight, rightHeight);
|
||||
newHeight += st::profileBlocksTop + blocksHeight + st::profileBlocksBottom;
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
void InnerWidget::onBlockHeightUpdated() {
|
||||
refreshBlocksPositions();
|
||||
|
||||
int naturalHeight = countHeight();
|
||||
int notDisplayedAtBottom = naturalHeight - _visibleBottom;
|
||||
if (notDisplayedAtBottom < 0) {
|
||||
_addedHeight = -notDisplayedAtBottom;
|
||||
} else {
|
||||
_addedHeight = 0;
|
||||
}
|
||||
if (naturalHeight + _addedHeight != height()) {
|
||||
resize(width(), naturalHeight + _addedHeight);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Profile
|
||||
|
|
|
@ -51,14 +51,37 @@ public:
|
|||
signals:
|
||||
void cancelled();
|
||||
|
||||
private slots:
|
||||
void onBlockHeightUpdated();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
|
||||
private:
|
||||
void createBlocks();
|
||||
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth);
|
||||
|
||||
// Counts the natural widget height after resizing of child widgets.
|
||||
int countHeight() const;
|
||||
|
||||
enum class Mode {
|
||||
OneColumn,
|
||||
TwoColumn,
|
||||
};
|
||||
enum class BlockSide {
|
||||
Left,
|
||||
Right,
|
||||
};
|
||||
int countBlocksLeft(int newWidth) const;
|
||||
Mode countBlocksMode(int newWidth) const;
|
||||
int countLeftColumnWidth(int newWidth) const;
|
||||
int countBlocksHeight(BlockSide countSide) const;
|
||||
void resizeBlocks(int newWidth);
|
||||
void refreshBlocksPositions();
|
||||
|
||||
// Sometimes height of this widget is larger than it is required
|
||||
// so that it is allowed to scroll down to the desired position.
|
||||
// When resizing with scroll moving up the additional height may be decreased.
|
||||
|
@ -73,8 +96,18 @@ private:
|
|||
int _visibleBottom = 0;
|
||||
|
||||
ChildWidget<CoverWidget> _cover;
|
||||
QList<BlockWidget*> _blocks;
|
||||
|
||||
int _blocksLeft = 0; // Caching countBlocksLeft() result.
|
||||
int _blocksTop = 0;
|
||||
int _columnDivider = 0;
|
||||
int _leftColumnWidth = 0; // Caching countLeftColumnWidth() result.
|
||||
struct Block {
|
||||
BlockWidget *block;
|
||||
BlockSide side;
|
||||
};
|
||||
QList<Block> _blocks;
|
||||
|
||||
Mode _mode = Mode::OneColumn;
|
||||
};
|
||||
|
||||
} // namespace Profile
|
||||
|
|
40
Telegram/SourceFiles/profile/profile_invite_link_widget.cpp
Normal file
40
Telegram/SourceFiles/profile/profile_invite_link_widget.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_invite_link_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
InviteLinkWidget::InviteLinkWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_invite_link_section))
|
||||
{
|
||||
show();
|
||||
}
|
||||
|
||||
int InviteLinkWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
} // namespace Profile
|
37
Telegram/SourceFiles/profile/profile_invite_link_widget.h
Normal file
37
Telegram/SourceFiles/profile/profile_invite_link_widget.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class InviteLinkWidget : public BlockWidget {
|
||||
public:
|
||||
InviteLinkWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
51
Telegram/SourceFiles/profile/profile_members_widget.cpp
Normal file
51
Telegram/SourceFiles/profile/profile_members_widget.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_members_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
MembersWidget::MembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section))
|
||||
{
|
||||
show();
|
||||
}
|
||||
|
||||
int MembersWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
ChannelMembersWidget::ChannelMembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section))
|
||||
{
|
||||
show();
|
||||
}
|
||||
|
||||
int ChannelMembersWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
} // namespace Profile
|
47
Telegram/SourceFiles/profile/profile_members_widget.h
Normal file
47
Telegram/SourceFiles/profile/profile_members_widget.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class MembersWidget : public BlockWidget {
|
||||
public:
|
||||
MembersWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
};
|
||||
|
||||
class ChannelMembersWidget : public BlockWidget {
|
||||
public:
|
||||
ChannelMembersWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
40
Telegram/SourceFiles/profile/profile_settings_widget.cpp
Normal file
40
Telegram/SourceFiles/profile/profile_settings_widget.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_settings_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
SettingsWidget::SettingsWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_settings_section))
|
||||
{
|
||||
show();
|
||||
}
|
||||
|
||||
int SettingsWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
} // namespace Profile
|
37
Telegram/SourceFiles/profile/profile_settings_widget.h
Normal file
37
Telegram/SourceFiles/profile/profile_settings_widget.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class SettingsWidget : public BlockWidget {
|
||||
public:
|
||||
SettingsWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
40
Telegram/SourceFiles/profile/profile_shared_media_widget.cpp
Normal file
40
Telegram/SourceFiles/profile/profile_shared_media_widget.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "profile/profile_shared_media_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
SharedMediaWidget::SharedMediaWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_shared_media))
|
||||
{
|
||||
show();
|
||||
}
|
||||
|
||||
int SharedMediaWidget::resizeGetHeight(int newWidth) {
|
||||
int newHeight = contentTop();
|
||||
|
||||
return newHeight;
|
||||
}
|
||||
|
||||
} // namespace Profile
|
37
Telegram/SourceFiles/profile/profile_shared_media_widget.h
Normal file
37
Telegram/SourceFiles/profile/profile_shared_media_widget.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class SharedMediaWidget : public BlockWidget {
|
||||
public:
|
||||
SharedMediaWidget(QWidget *parent, PeerData *peer);
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Profile
|
|
@ -115,7 +115,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, PeerData *peer) : TWidget(0)
|
|||
if (_peerUser->blocked == UserIsBlocked) {
|
||||
_blockUser.setText(lang(_peerUser->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user));
|
||||
}
|
||||
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(_peerUser->id)) : _peerUser->phone);
|
||||
_phoneText = App::formatPhone(_peerUser->phone().isEmpty() ? App::phoneFromSharedContact(peerToUser(_peerUser->id)) : _peerUser->phone());
|
||||
PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0;
|
||||
if (userPhoto && userPhoto->date) {
|
||||
_photoLink.reset(new PhotoOpenClickHandler(userPhoto, _peer));
|
||||
|
@ -168,7 +168,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, PeerData *peer) : TWidget(0)
|
|||
QString maxStr;
|
||||
if (_peerUser->botInfo && !_peerUser->botInfo->cantJoinGroups) {
|
||||
maxStr = lang(_sendMessage.textWidth() > _inviteToGroup.textWidth() ? lng_profile_send_message : lng_profile_invite_to_group);
|
||||
} else if (!_peerUser->phone.isEmpty()) {
|
||||
} else if (!_peerUser->phone().isEmpty()) {
|
||||
maxStr = lang(_sendMessage.textWidth() > _shareContact.textWidth() ? lng_profile_send_message : lng_profile_share_contact);
|
||||
} else {
|
||||
maxStr = lang(lng_profile_send_message);
|
||||
|
@ -193,13 +193,13 @@ ProfileInner::ProfileInner(ProfileWidget *profile, PeerData *peer) : TWidget(0)
|
|||
|
||||
// about
|
||||
if (_peerUser) {
|
||||
if (!_peerUser->about.isEmpty()) {
|
||||
_about.setText(st::linkFont, _peerUser->about, _peerUser->botInfo ? _historyBotNoMonoOptions : _historyTextNoMonoOptions);
|
||||
if (!_peerUser->about().isEmpty()) {
|
||||
_about.setText(st::linkFont, _peerUser->about(), _peerUser->botInfo ? _historyBotNoMonoOptions : _historyTextNoMonoOptions);
|
||||
}
|
||||
updateBotLinksVisibility();
|
||||
} else {
|
||||
if (_peerChannel && !_peerChannel->about.isEmpty()) {
|
||||
_about.setText(st::linkFont, _peerChannel->about, _historyTextNoMonoOptions);
|
||||
if (_peerChannel && !_peerChannel->about().isEmpty()) {
|
||||
_about.setText(st::linkFont, _peerChannel->about(), _historyTextNoMonoOptions);
|
||||
}
|
||||
_botSettings.hide();
|
||||
_botHelp.hide();
|
||||
|
@ -538,10 +538,10 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) {
|
|||
_photoLink.clear();
|
||||
}
|
||||
if (_peerUser) {
|
||||
if (_peerUser->about.isEmpty()) {
|
||||
if (_peerUser->about().isEmpty()) {
|
||||
_about = Text(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right());
|
||||
} else {
|
||||
_about.setText(st::linkFont, _peerUser->about, _peerUser->botInfo ? _historyBotNoMonoOptions : _historyTextNoMonoOptions);
|
||||
_about.setText(st::linkFont, _peerUser->about(), _peerUser->botInfo ? _historyBotNoMonoOptions : _historyTextNoMonoOptions);
|
||||
}
|
||||
updateBotLinksVisibility();
|
||||
resizeEvent(0);
|
||||
|
@ -557,10 +557,10 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) {
|
|||
_members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 1));
|
||||
_admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1));
|
||||
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
|
||||
if (_peerChannel->about.isEmpty()) {
|
||||
if (_peerChannel->about().isEmpty()) {
|
||||
_about = Text(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right());
|
||||
} else {
|
||||
_about.setText(st::linkFont, _peerChannel->about, _historyTextNoMonoOptions);
|
||||
_about.setText(st::linkFont, _peerChannel->about(), _historyTextNoMonoOptions);
|
||||
}
|
||||
showAll();
|
||||
resizeEvent(0);
|
||||
|
@ -607,7 +607,7 @@ void ProfileInner::peerUpdated(PeerData *data) {
|
|||
if (data == _peer) {
|
||||
PhotoData *photo = 0;
|
||||
if (_peerUser) {
|
||||
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(_peerUser->id)) : _peerUser->phone);
|
||||
_phoneText = App::formatPhone(_peerUser->phone().isEmpty() ? App::phoneFromSharedContact(peerToUser(_peerUser->id)) : _peerUser->phone());
|
||||
if (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) photo = App::photo(_peerUser->photoId);
|
||||
if (_wasBlocked != _peerUser->blocked) {
|
||||
_wasBlocked = _peerUser->blocked;
|
||||
|
@ -1668,7 +1668,7 @@ void ProfileInner::showAll() {
|
|||
_createInvitationLink.hide();
|
||||
_invitationLink.hide();
|
||||
_sendMessage.show();
|
||||
if (_peerUser->phone.isEmpty()) {
|
||||
if (_peerUser->phone().isEmpty()) {
|
||||
_shareContact.hide();
|
||||
if (_peerUser->botInfo && !_peerUser->botInfo->cantJoinGroups) {
|
||||
_inviteToGroup.show();
|
||||
|
@ -1950,7 +1950,7 @@ void ProfileWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) {
|
|||
p.drawSprite(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), st::topBarBackImg);
|
||||
p.setFont(st::topBarBackFont->f);
|
||||
p.setPen(st::topBarBackColor->p);
|
||||
p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, lang(peer()->isUser() ? lng_profile_info : ((peer()->isChat() || peer()->isMegagroup()) ? lng_profile_group_info : lng_profile_channel_info)));
|
||||
// p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, lang(peer()->isUser() ? lng_profile_info : ((peer()->isChat() || peer()->isMegagroup()) ? lng_profile_group_info : lng_profile_channel_info)));
|
||||
}
|
||||
|
||||
void ProfileWidget::topBarClick() {
|
||||
|
|
|
@ -123,7 +123,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent)
|
|||
, _a_photo(animation(this, &SettingsInner::step_photo))
|
||||
|
||||
// contact info
|
||||
, _phoneText(self() ? App::formatPhone(self()->phone) : QString())
|
||||
, _phoneText(self() ? App::formatPhone(self()->phone()) : QString())
|
||||
, _chooseUsername(this, (self() && !self()->username.isEmpty()) ? ('@' + self()->username) : lang(lng_settings_choose_username))
|
||||
|
||||
// notifications
|
||||
|
|
|
@ -262,6 +262,18 @@ void PeerData::fillNames() {
|
|||
}
|
||||
}
|
||||
|
||||
bool UserData::setAbout(const QString &newAbout) {
|
||||
if (_about == newAbout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_about = newAbout;
|
||||
Notify::PeerUpdate update(this);
|
||||
update.flags |= Notify::PeerUpdateFlag::AboutChanged;
|
||||
Notify::peerUpdatedDelayed(update);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UserData::setName(const QString &newFirstName, const QString &newLastName, const QString &newPhoneName, const QString &newUsername) {
|
||||
setNameDelayed(newFirstName, newLastName, newPhoneName, newUsername);
|
||||
Notify::peerUpdatedSendDelayed();
|
||||
|
@ -286,7 +298,7 @@ void UserData::setNameDelayed(const QString &newFirstName, const QString &newLas
|
|||
}
|
||||
|
||||
void UserData::setPhone(const QString &newPhone) {
|
||||
phone = newPhone;
|
||||
_phone = newPhone;
|
||||
}
|
||||
|
||||
void UserData::setBotInfoVersion(int version) {
|
||||
|
@ -480,6 +492,18 @@ void ChannelData::fullUpdated() {
|
|||
_lastFullUpdate = getms(true);
|
||||
}
|
||||
|
||||
bool ChannelData::setAbout(const QString &newAbout) {
|
||||
if (_about == newAbout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_about = newAbout;
|
||||
Notify::PeerUpdate update(this);
|
||||
update.flags |= Notify::PeerUpdateFlag::AboutChanged;
|
||||
Notify::peerUpdatedDelayed(update);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChannelData::flagsUpdated() {
|
||||
if (isMegagroup()) {
|
||||
if (!mgInfo) {
|
||||
|
|
|
@ -442,7 +442,7 @@ public:
|
|||
// When actually trying to share contact we perform
|
||||
// a full check by canShareThisContact() call.
|
||||
bool canShareThisContactFast() const {
|
||||
return !phone.isEmpty();
|
||||
return !_phone.isEmpty();
|
||||
}
|
||||
|
||||
MTPInputUser inputUser;
|
||||
|
@ -450,7 +450,9 @@ public:
|
|||
QString firstName;
|
||||
QString lastName;
|
||||
QString username;
|
||||
QString phone;
|
||||
const QString &phone() const {
|
||||
return _phone;
|
||||
}
|
||||
QString nameOrPhone;
|
||||
Text phoneText;
|
||||
TimeId onlineTill = 0;
|
||||
|
@ -461,7 +463,10 @@ public:
|
|||
Photos photos;
|
||||
int photosCount = -1; // -1 not loaded, 0 all loaded
|
||||
|
||||
QString about;
|
||||
bool setAbout(const QString &newAbout);
|
||||
const QString &about() const {
|
||||
return _about;
|
||||
}
|
||||
|
||||
BotInfo *botInfo = nullptr;
|
||||
|
||||
|
@ -474,6 +479,8 @@ public:
|
|||
|
||||
private:
|
||||
QString _restrictionReason;
|
||||
QString _about;
|
||||
QString _phone;
|
||||
|
||||
};
|
||||
|
||||
|
@ -669,7 +676,13 @@ public:
|
|||
|
||||
MTPinputChannel inputChannel;
|
||||
|
||||
QString username, about;
|
||||
QString username;
|
||||
|
||||
// Returns true if about text was changed.
|
||||
bool setAbout(const QString &newAbout);
|
||||
const QString &about() const {
|
||||
return _about;
|
||||
}
|
||||
|
||||
int count = 1;
|
||||
int adminsCount = 1;
|
||||
|
@ -791,11 +804,11 @@ public:
|
|||
~ChannelData();
|
||||
|
||||
private:
|
||||
|
||||
PtsWaiter _ptsWaiter;
|
||||
uint64 _lastFullUpdate = 0;
|
||||
|
||||
QString _restrictionReason;
|
||||
QString _about;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -2472,9 +2472,9 @@ void PhoneInput::focusInEvent(QFocusEvent *e) {
|
|||
void PhoneInput::clearText() {
|
||||
QString phone;
|
||||
if (App::self()) {
|
||||
QVector<int> newPattern = phoneNumberParse(App::self()->phone);
|
||||
QVector<int> newPattern = phoneNumberParse(App::self()->phone());
|
||||
if (!newPattern.isEmpty()) {
|
||||
phone = App::self()->phone.mid(0, newPattern.at(0));
|
||||
phone = App::self()->phone().mid(0, newPattern.at(0));
|
||||
}
|
||||
}
|
||||
setText(phone);
|
||||
|
|
|
@ -31,11 +31,36 @@ namespace {
|
|||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
TextParseOptions _labelMarkedOptions = {
|
||||
TextParseMultiline | TextParseLinks | TextParseHashtags | TextParseMentions | TextParseBotCommands, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
}
|
||||
|
||||
FlatLabel::FlatLabel(QWidget *parent, const QString &text, const style::flatLabel &st, const style::textStyle &tst) : TWidget(parent),
|
||||
_text(st.width ? st.width : QFIXED_MAX), _st(st), _tst(tst), _opacity(1) {
|
||||
setRichText(text);
|
||||
FlatLabel::FlatLabel(QWidget *parent, const style::flatLabel &st, const style::textStyle &tst) : TWidget(parent)
|
||||
, _text(st.width ? st.width : QFIXED_MAX)
|
||||
, _st(st)
|
||||
, _tst(tst)
|
||||
, _contextCopyText(lang(lng_context_copy_text)) {
|
||||
init();
|
||||
}
|
||||
|
||||
FlatLabel::FlatLabel(QWidget *parent, const QString &text, InitType initType, const style::flatLabel &st, const style::textStyle &tst) : TWidget(parent)
|
||||
, _text(st.width ? st.width : QFIXED_MAX)
|
||||
, _st(st)
|
||||
, _tst(tst)
|
||||
, _contextCopyText(lang(lng_context_copy_text)) {
|
||||
if (initType == InitType::Rich) {
|
||||
setRichText(text);
|
||||
} else {
|
||||
setText(text);
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
void FlatLabel::init() {
|
||||
_trippleClickTimer.setSingleShot(true);
|
||||
|
||||
_touchSelectTimer.setSingleShot(true);
|
||||
|
@ -58,15 +83,31 @@ void FlatLabel::setRichText(const QString &text) {
|
|||
setMouseTracking(_selectable || _text.hasLinks());
|
||||
}
|
||||
|
||||
void FlatLabel::setMarkedText(const TextWithEntities &textWithEntities) {
|
||||
textstyleSet(&_tst);
|
||||
_text.setMarkedText(_st.font, textWithEntities, _labelMarkedOptions);
|
||||
refreshSize();
|
||||
textstyleRestore();
|
||||
setMouseTracking(_selectable || _text.hasLinks());
|
||||
}
|
||||
|
||||
void FlatLabel::setSelectable(bool selectable) {
|
||||
_selectable = selectable;
|
||||
setMouseTracking(_selectable || _text.hasLinks());
|
||||
}
|
||||
|
||||
void FlatLabel::setDoubleClickSelectsParagraph(bool doubleClickSelectsParagraph) {
|
||||
_doubleClickSelectsParagraph = doubleClickSelectsParagraph;
|
||||
}
|
||||
|
||||
void FlatLabel::setContextCopyText(const QString ©Text) {
|
||||
_contextCopyText = copyText;
|
||||
}
|
||||
|
||||
void FlatLabel::setExpandLinksMode(ExpandLinksMode mode) {
|
||||
_contextExpandLinksMode = mode;
|
||||
}
|
||||
|
||||
void FlatLabel::resizeToWidth(int32 width) {
|
||||
textstyleSet(&_tst);
|
||||
_allowedWidth = width;
|
||||
|
@ -74,6 +115,10 @@ void FlatLabel::resizeToWidth(int32 width) {
|
|||
textstyleRestore();
|
||||
}
|
||||
|
||||
int FlatLabel::naturalWidth() const {
|
||||
return _text.maxWidth();
|
||||
}
|
||||
|
||||
int FlatLabel::countTextWidth() const {
|
||||
return _allowedWidth ? (_allowedWidth - _st.margin.left() - _st.margin.right()) : (_st.width ? _st.width : _text.maxWidth());
|
||||
}
|
||||
|
@ -95,6 +140,10 @@ void FlatLabel::setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk) {
|
|||
_text.setLink(lnkIndex, lnk);
|
||||
}
|
||||
|
||||
void FlatLabel::setClickHandlerHook(ClickHandlerHook &&hook) {
|
||||
_clickHandlerHook = std_::move(hook);
|
||||
}
|
||||
|
||||
void FlatLabel::mouseMoveEvent(QMouseEvent *e) {
|
||||
_lastMousePos = e->globalPos();
|
||||
dragActionUpdate();
|
||||
|
@ -177,7 +226,9 @@ Text::StateResult FlatLabel::dragActionFinish(const QPoint &p, Qt::MouseButton b
|
|||
_selectionType = TextSelectType::Letters;
|
||||
|
||||
if (activated) {
|
||||
App::activateClickHandler(activated, button);
|
||||
if (_clickHandlerHook.isNull() || _clickHandlerHook.call(activated, button)) {
|
||||
App::activateClickHandler(activated, button);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
@ -194,7 +245,7 @@ void FlatLabel::mouseDoubleClickEvent(QMouseEvent *e) {
|
|||
if (((_dragAction == Selecting) || (_dragAction == NoDrag)) && _selectionType == TextSelectType::Letters) {
|
||||
if (state.uponSymbol) {
|
||||
_dragSymbol = state.symbol;
|
||||
_selectionType = TextSelectType::Words;
|
||||
_selectionType = _doubleClickSelectsParagraph ? TextSelectType::Paragraphs : TextSelectType::Words;
|
||||
if (_dragAction == NoDrag) {
|
||||
_dragAction = Selecting;
|
||||
_selection = { state.symbol, state.symbol };
|
||||
|
@ -219,7 +270,9 @@ void FlatLabel::leaveEvent(QEvent *e) {
|
|||
|
||||
void FlatLabel::focusOutEvent(QFocusEvent *e) {
|
||||
if (!_selection.empty()) {
|
||||
_savedSelection = _selection;
|
||||
if (_contextMenu) {
|
||||
_savedSelection = _selection;
|
||||
}
|
||||
_selection = { 0, 0 };
|
||||
update();
|
||||
}
|
||||
|
@ -338,12 +391,12 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason)
|
|||
|
||||
_contextMenuClickHandler = ClickHandler::getActive();
|
||||
|
||||
if (fullSelection) {
|
||||
_contextMenu->addAction(contextCopyText(), this, SLOT(onCopyContextText()))->setEnabled(true);
|
||||
} else if (uponSelection) {
|
||||
if (fullSelection && !_contextCopyText.isEmpty()) {
|
||||
_contextMenu->addAction(_contextCopyText, this, SLOT(onCopyContextText()))->setEnabled(true);
|
||||
} else if (uponSelection && !fullSelection) {
|
||||
_contextMenu->addAction(lang(lng_context_copy_selected), this, SLOT(onCopySelectedText()))->setEnabled(true);
|
||||
} else if (!hasSelection) {
|
||||
_contextMenu->addAction(contextCopyText(), this, SLOT(onCopyContextText()))->setEnabled(true);
|
||||
} else if (!hasSelection && !_contextCopyText.isEmpty()) {
|
||||
_contextMenu->addAction(_contextCopyText, this, SLOT(onCopyContextText()))->setEnabled(true);
|
||||
}
|
||||
|
||||
QString linkCopyToClipboardText = _contextMenuClickHandler ? _contextMenuClickHandler->copyToClipboardContextItemText() : QString();
|
||||
|
@ -361,19 +414,15 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason)
|
|||
}
|
||||
}
|
||||
|
||||
QString FlatLabel::contextCopyText() const {
|
||||
return _contextCopyText.isEmpty() ? lang(lng_context_copy_text) : _contextCopyText;
|
||||
}
|
||||
|
||||
void FlatLabel::onCopySelectedText() {
|
||||
auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
|
||||
if (!selection.empty()) {
|
||||
QApplication::clipboard()->setText(_text.originalText(selection, ExpandLinksAll));
|
||||
QApplication::clipboard()->setText(_text.originalText(selection, _contextExpandLinksMode));
|
||||
}
|
||||
}
|
||||
|
||||
void FlatLabel::onCopyContextText() {
|
||||
QApplication::clipboard()->setText(_text.originalText({ 0, 0xFFFF }, ExpandLinksAll));
|
||||
QApplication::clipboard()->setText(_text.originalText({ 0, 0xFFFF }, _contextExpandLinksMode));
|
||||
}
|
||||
|
||||
void FlatLabel::onCopyContextUrl() {
|
||||
|
@ -514,7 +563,7 @@ Text::StateResult FlatLabel::getTextState(const QPoint &m) const {
|
|||
|
||||
textstyleSet(&_tst);
|
||||
Text::StateResult state;
|
||||
if (_st.maxHeight && _st.maxHeight < _fullTextHeight) {
|
||||
if (_st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth())) {
|
||||
auto lineHeight = qMax(_tst.lineHeight, _st.font->height);
|
||||
request.lines = qMax(_st.maxHeight / lineHeight, 1);
|
||||
state = _text.getStateElided(m.x() - _st.margin.left(), m.y() - _st.margin.top(), textWidth, request);
|
||||
|
@ -538,7 +587,7 @@ void FlatLabel::paintEvent(QPaintEvent *e) {
|
|||
textstyleSet(&_tst);
|
||||
int textWidth = width() - _st.margin.left() - _st.margin.right();
|
||||
auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
|
||||
if (_st.maxHeight && _st.maxHeight < _fullTextHeight) {
|
||||
if (_st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth())) {
|
||||
auto lineHeight = qMax(_tst.lineHeight, _st.font->height);
|
||||
auto lines = qMax(_st.maxHeight / lineHeight, 1);
|
||||
_text.drawElided(p, _st.margin.left(), _st.margin.top(), textWidth, lines, _st.align, e->rect().y(), e->rect().bottom(), 0, false, selection);
|
||||
|
|
|
@ -24,19 +24,32 @@ class FlatLabel : public TWidget, public ClickHandlerHost {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FlatLabel(QWidget *parent, const QString &text, const style::flatLabel &st = st::labelDefFlat, const style::textStyle &tst = st::defaultTextStyle);
|
||||
FlatLabel(QWidget *parent, const style::flatLabel &st = st::labelDefFlat, const style::textStyle &tst = st::defaultTextStyle);
|
||||
|
||||
enum class InitType {
|
||||
Simple,
|
||||
Rich,
|
||||
};
|
||||
FlatLabel(QWidget *parent, const QString &text, InitType initType, const style::flatLabel &st = st::labelDefFlat, const style::textStyle &tst = st::defaultTextStyle);
|
||||
|
||||
void setOpacity(float64 o);
|
||||
|
||||
void setText(const QString &text);
|
||||
void setRichText(const QString &text);
|
||||
void setMarkedText(const TextWithEntities &textWithEntities);
|
||||
void setSelectable(bool selectable);
|
||||
void setDoubleClickSelectsParagraph(bool doubleClickSelectsParagraph);
|
||||
void setContextCopyText(const QString ©Text);
|
||||
void setExpandLinksMode(ExpandLinksMode mode);
|
||||
|
||||
void resizeToWidth(int32 width);
|
||||
int naturalWidth() const;
|
||||
|
||||
void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk);
|
||||
|
||||
using ClickHandlerHook = Function<bool, const ClickHandlerPtr &, Qt::MouseButton>;
|
||||
void setClickHandlerHook(ClickHandlerHook &&hook);
|
||||
|
||||
// ClickHandlerHost interface
|
||||
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
||||
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
||||
|
@ -67,6 +80,8 @@ private slots:
|
|||
void onExecuteDrag();
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
Text::StateResult dragActionUpdate();
|
||||
Text::StateResult dragActionStart(const QPoint &p, Qt::MouseButton button);
|
||||
Text::StateResult dragActionFinish(const QPoint &p, Qt::MouseButton button);
|
||||
|
@ -83,12 +98,11 @@ private:
|
|||
FromTouch,
|
||||
};
|
||||
void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason);
|
||||
QString contextCopyText() const;
|
||||
|
||||
Text _text;
|
||||
style::flatLabel _st;
|
||||
style::textStyle _tst;
|
||||
float64 _opacity;
|
||||
float64 _opacity = 1.;
|
||||
|
||||
int _allowedWidth = 0;
|
||||
int _fullTextHeight = 0;
|
||||
|
@ -97,6 +111,7 @@ private:
|
|||
bool _selectable = false;
|
||||
TextSelection _selection, _savedSelection;
|
||||
TextSelectType _selectionType = TextSelectType::Letters;
|
||||
bool _doubleClickSelectsParagraph = false;
|
||||
|
||||
enum DragAction {
|
||||
NoDrag = 0x00,
|
||||
|
@ -117,6 +132,9 @@ private:
|
|||
PopupMenu *_contextMenu = nullptr;
|
||||
ClickHandlerPtr _contextMenuClickHandler;
|
||||
QString _contextCopyText;
|
||||
ExpandLinksMode _contextExpandLinksMode = ExpandLinksAll;
|
||||
|
||||
ClickHandlerHook _clickHandlerHook;
|
||||
|
||||
// text selection and context menu by touch support (at least Windows Surface tablets)
|
||||
bool _touchSelect = false;
|
||||
|
|
|
@ -312,6 +312,20 @@ public:
|
|||
return _widget;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
if (_widget) {
|
||||
delete _widget;
|
||||
_widget = nullptr;
|
||||
}
|
||||
}
|
||||
void destroyDelayed() {
|
||||
if (_widget) {
|
||||
_widget->hide();
|
||||
_widget->deleteLater();
|
||||
_widget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T *_widget;
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ void TopBarWidget::onInfoClicked() {
|
|||
void TopBarWidget::onAddContact() {
|
||||
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
|
||||
UserData *u = p ? p->asUser() : 0;
|
||||
if (u) Ui::showLayer(new AddContactBox(u->firstName, u->lastName, u->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(u->id)) : u->phone));
|
||||
if (u) Ui::showLayer(new AddContactBox(u->firstName, u->lastName, u->phone().isEmpty() ? App::phoneFromSharedContact(peerToUser(u->id)) : u->phone()));
|
||||
}
|
||||
|
||||
void TopBarWidget::onEdit() {
|
||||
|
|
|
@ -1213,12 +1213,18 @@
|
|||
<ClCompile Include="SourceFiles\passcodewidget.cpp" />
|
||||
<ClCompile Include="SourceFiles\playerwidget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profilewidget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_actions_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_block_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_cover.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_cover_drop_area.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_fixed_bar.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_info_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_inner_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_invite_link_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_members_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_section_memento.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_settings_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_shared_media_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_userpic_button.cpp" />
|
||||
<ClCompile Include="SourceFiles\profile\profile_widget.cpp" />
|
||||
<ClCompile Include="SourceFiles\pspecific_linux.cpp">
|
||||
|
@ -1549,21 +1555,27 @@
|
|||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_fixed_bar.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SourceFiles\profile\profile_block_widget.h">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing profile_block_widget.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_block_widget.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing profile_block_widget.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_block_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing profile_block_widget.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_block_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="SourceFiles\profile\profile_actions_widget.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_cover_drop_area.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_info_widget.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_invite_link_widget.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_members_widget.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_section_memento.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_settings_widget.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_shared_media_widget.h" />
|
||||
<ClInclude Include="SourceFiles\profile\profile_userpic_button.h" />
|
||||
<ClInclude Include="SourceFiles\serialize\serialize_common.h" />
|
||||
<ClInclude Include="SourceFiles\serialize\serialize_document.h" />
|
||||
|
|
|
@ -1188,18 +1188,6 @@
|
|||
<ClCompile Include="SourceFiles\profile\profile_section_memento.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_block_widget.cpp">
|
||||
<Filter>GeneratedFiles\Deploy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_profile_block_widget.cpp">
|
||||
<Filter>GeneratedFiles\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_profile_block_widget.cpp">
|
||||
<Filter>GeneratedFiles\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_block_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\ui\buttons\round_button.cpp">
|
||||
<Filter>SourceFiles\ui\buttons</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1215,6 +1203,36 @@
|
|||
<ClCompile Include="SourceFiles\profile\profile_userpic_button.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Deploy\moc_profile_block_widget.cpp">
|
||||
<Filter>GeneratedFiles\Deploy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_profile_block_widget.cpp">
|
||||
<Filter>GeneratedFiles\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_profile_block_widget.cpp">
|
||||
<Filter>GeneratedFiles\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_block_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_info_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_actions_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_invite_link_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_members_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_settings_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\profile\profile_shared_media_widget.cpp">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\stdafx.h">
|
||||
|
@ -1418,6 +1436,24 @@
|
|||
<ClInclude Include="SourceFiles\profile\profile_userpic_button.h">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\profile\profile_info_widget.h">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\profile\profile_actions_widget.h">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\profile\profile_invite_link_widget.h">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\profile\profile_members_widget.h">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\profile\profile_settings_widget.h">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\profile\profile_shared_media_widget.h">
|
||||
<Filter>SourceFiles\profile</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SourceFiles\application.h">
|
||||
|
|
Loading…
Add table
Reference in a new issue