mirror of https://github.com/procxx/kepka.git
Delete for everyone checkbox added. Various bugfixes.
This commit is contained in:
parent
218f991547
commit
eec5b78054
|
@ -959,6 +959,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_selected_delete_sure_this" = "Do you want to delete this message?";
|
"lng_selected_delete_sure_this" = "Do you want to delete this message?";
|
||||||
"lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?";
|
"lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?";
|
||||||
"lng_delete_photo_sure" = "Do you want to delete this photo?";
|
"lng_delete_photo_sure" = "Do you want to delete this photo?";
|
||||||
|
"lng_delete_for_everyone_this_hint" = "This will delete it for everyone in this chat.";
|
||||||
|
"lng_delete_for_everyone_hint" = "This will delete {count:_not_used_|it|them} for everyone in this chat.";
|
||||||
|
"lng_delete_for_me_chat_this_hint" = "This will delete it just for you, not for other participants of the chat.";
|
||||||
|
"lng_delete_for_me_chat_hint" = "This will delete {count:_not_used_|it|them} just for you, not for other participants of the chat.";
|
||||||
|
"lng_delete_for_me_this_hint" = "This will delete it just for you.";
|
||||||
|
"lng_delete_for_me_hint" = "This will delete {count:_not_used_|it|them} just for you.";
|
||||||
|
"lng_delete_for_everyone_check" = "Delete for everyone";
|
||||||
|
"lng_delete_for_other_check" = "Delete for {user}";
|
||||||
"lng_box_delete" = "Delete";
|
"lng_box_delete" = "Delete";
|
||||||
"lng_box_leave" = "Leave";
|
"lng_box_leave" = "Leave";
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,16 @@ defaultBoxButton: RoundButton(defaultLightButton) {
|
||||||
font: boxButtonFont;
|
font: boxButtonFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxTextStyle: TextStyle(defaultTextStyle) {
|
||||||
|
font: font(boxFontSize);
|
||||||
|
linkFont: font(boxFontSize);
|
||||||
|
linkFontOver: font(boxFontSize underline);
|
||||||
|
}
|
||||||
|
|
||||||
|
boxLabelStyle: TextStyle(boxTextStyle) {
|
||||||
|
lineHeight: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
attentionBoxButton: RoundButton(defaultBoxButton) {
|
attentionBoxButton: RoundButton(defaultBoxButton) {
|
||||||
textFg: attentionButtonFg;
|
textFg: attentionButtonFg;
|
||||||
textFgOver: attentionButtonFgOver;
|
textFgOver: attentionButtonFgOver;
|
||||||
|
@ -46,7 +56,7 @@ attentionBoxButton: RoundButton(defaultBoxButton) {
|
||||||
defaultBoxCheckbox: Checkbox(defaultCheckbox) {
|
defaultBoxCheckbox: Checkbox(defaultCheckbox) {
|
||||||
width: -46px;
|
width: -46px;
|
||||||
textPosition: point(34px, 1px);
|
textPosition: point(34px, 1px);
|
||||||
font: boxTextFont;
|
style: boxTextStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
boxRoundShadow: Shadow {
|
boxRoundShadow: Shadow {
|
||||||
|
@ -108,12 +118,9 @@ boxMediumSkip: 20px;
|
||||||
boxButtonPadding: margins(8px, 12px, 13px, 12px);
|
boxButtonPadding: margins(8px, 12px, 13px, 12px);
|
||||||
boxLayerButtonPadding: margins(8px, 8px, 8px, 8px);
|
boxLayerButtonPadding: margins(8px, 8px, 8px, 8px);
|
||||||
boxLabel: FlatLabel(defaultFlatLabel) {
|
boxLabel: FlatLabel(defaultFlatLabel) {
|
||||||
|
width: 285px;
|
||||||
align: align(topleft);
|
align: align(topleft);
|
||||||
style: TextStyle(defaultTextStyle) {
|
style: boxLabelStyle;
|
||||||
font: font(boxFontSize);
|
|
||||||
linkFont: font(boxFontSize);
|
|
||||||
linkFontOver: font(boxFontSize underline);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
countryRowHeight: 36px;
|
countryRowHeight: 36px;
|
||||||
|
@ -131,10 +138,6 @@ countriesScroll: ScrollArea(boxLayerScroll) {
|
||||||
deltab: 3px;
|
deltab: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
boxTextStyle: TextStyle(defaultTextStyle) {
|
|
||||||
lineHeight: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
boxPhotoTitleFont: font(16px semibold);
|
boxPhotoTitleFont: font(16px semibold);
|
||||||
boxPhotoTitlePosition: point(28px, 20px);
|
boxPhotoTitlePosition: point(28px, 20px);
|
||||||
boxPhotoPadding: margins(28px, 28px, 28px, 18px);
|
boxPhotoPadding: margins(28px, 28px, 28px, 18px);
|
||||||
|
|
|
@ -112,7 +112,7 @@ base::lambda<void()> ConfirmBox::generateInformCallback(const base::lambda_copy<
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmBox::init(const QString &text) {
|
void ConfirmBox::init(const QString &text) {
|
||||||
_text.setText(st::boxTextStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
|
_text.setText(st::boxLabelStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmBox::prepare() {
|
void ConfirmBox::prepare() {
|
||||||
|
@ -125,7 +125,7 @@ void ConfirmBox::prepare() {
|
||||||
|
|
||||||
void ConfirmBox::textUpdated() {
|
void ConfirmBox::textUpdated() {
|
||||||
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
||||||
_textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight));
|
_textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxLabelStyle.lineHeight);
|
||||||
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxPadding.bottom());
|
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxPadding.bottom());
|
||||||
|
|
||||||
setMouseTracking(_text.hasLinks());
|
setMouseTracking(_text.hasLinks());
|
||||||
|
@ -219,7 +219,7 @@ InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, bas
|
||||||
}
|
}
|
||||||
|
|
||||||
MaxInviteBox::MaxInviteBox(QWidget*, const QString &link)
|
MaxInviteBox::MaxInviteBox(QWidget*, const QString &link)
|
||||||
: _text(st::boxTextStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right())
|
: _text(st::boxLabelStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right())
|
||||||
, _link(link) {
|
, _link(link) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ void MaxInviteBox::prepare() {
|
||||||
addButton(lang(lng_box_ok), [this] { closeBox(); });
|
addButton(lang(lng_box_ok), [this] { closeBox(); });
|
||||||
|
|
||||||
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
||||||
_textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight));
|
_textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxLabelStyle.lineHeight);
|
||||||
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxTextFont->height + st::boxTextFont->height * 2 + st::newGroupLinkPadding.bottom());
|
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxTextFont->height + st::boxTextFont->height * 2 + st::newGroupLinkPadding.bottom());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +302,8 @@ void ConvertToSupergroupBox::prepare() {
|
||||||
addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); });
|
addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); });
|
||||||
addButton(lang(lng_cancel), [this] { closeBox(); });
|
addButton(lang(lng_cancel), [this] { closeBox(); });
|
||||||
|
|
||||||
_text.setText(st::boxTextStyle, text.join('\n'), _confirmBoxTextOptions);
|
_text.setText(st::boxLabelStyle, text.join('\n'), _confirmBoxTextOptions);
|
||||||
_note.setText(st::boxTextStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
|
_note.setText(st::boxLabelStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
|
||||||
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
|
||||||
_textHeight = _text.countHeight(_textWidth);
|
_textHeight = _text.countHeight(_textWidth);
|
||||||
setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth));
|
setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth));
|
||||||
|
@ -408,54 +408,135 @@ bool PinMessageBox::pinFail(const RPCError &error) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RichDeleteMessageBox::RichDeleteMessageBox(QWidget*, ChannelData *channel, UserData *from, MsgId msgId)
|
DeleteMessagesBox::DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions) : _singleItem(true) {
|
||||||
: _channel(channel)
|
_ids.push_back(item->fullId());
|
||||||
, _from(from)
|
if (suggestModerateActions && item->suggestBanReportDeleteAll()) {
|
||||||
, _msgId(msgId)
|
_moderateFrom = item->from()->asUser();
|
||||||
, _text(this, lang(lng_selected_delete_sure_this), Ui::FlatLabel::InitType::Simple, st::boxLabel)
|
_moderateInChannel = item->history()->peer->asChannel();
|
||||||
, _banUser(this, lang(lng_ban_user), false, st::defaultBoxCheckbox)
|
}
|
||||||
, _reportSpam(this, lang(lng_report_spam), false, st::defaultBoxCheckbox)
|
|
||||||
, _deleteAll(this, lang(lng_delete_all_from), false, st::defaultBoxCheckbox) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichDeleteMessageBox::prepare() {
|
DeleteMessagesBox::DeleteMessagesBox(QWidget*, const SelectedItemSet &selected) {
|
||||||
t_assert(_channel != nullptr);
|
auto count = selected.size();
|
||||||
|
t_assert(count > 0);
|
||||||
|
_ids.reserve(count);
|
||||||
|
for_const (auto item, selected) {
|
||||||
|
_ids.push_back(item->fullId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteMessagesBox::prepare() {
|
||||||
|
auto text = QString();
|
||||||
|
if (_moderateFrom) {
|
||||||
|
t_assert(_moderateInChannel != nullptr);
|
||||||
|
text = lang(lng_selected_delete_sure_this);
|
||||||
|
_banUser.create(this, lang(lng_ban_user), false, st::defaultBoxCheckbox);
|
||||||
|
_reportSpam.create(this, lang(lng_report_spam), false, st::defaultBoxCheckbox);
|
||||||
|
_deleteAll.create(this, lang(lng_delete_all_from), false, st::defaultBoxCheckbox);
|
||||||
|
} else {
|
||||||
|
text = _singleItem ? lang(lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, _ids.size());
|
||||||
|
auto canDeleteAllForEveryone = true;
|
||||||
|
auto now = ::date(unixtime());
|
||||||
|
auto deleteForUser = (UserData*)nullptr;
|
||||||
|
auto peer = (PeerData*)nullptr;
|
||||||
|
auto forEveryoneText = lang(lng_delete_for_everyone_check);
|
||||||
|
for_const (auto fullId, _ids) {
|
||||||
|
if (auto item = App::histItemById(fullId)) {
|
||||||
|
peer = item->history()->peer;
|
||||||
|
if (!item->canDeleteForEveryone(now)) {
|
||||||
|
canDeleteAllForEveryone = false;
|
||||||
|
break;
|
||||||
|
} else if (auto user = item->history()->peer->asUser()) {
|
||||||
|
if (!deleteForUser || deleteForUser == user) {
|
||||||
|
deleteForUser = user;
|
||||||
|
forEveryoneText = lng_delete_for_other_check(lt_user, user->firstName);
|
||||||
|
} else {
|
||||||
|
forEveryoneText = lang(lng_delete_for_everyone_check);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
canDeleteAllForEveryone = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canDeleteAllForEveryone) {
|
||||||
|
_forEveryone.create(this, forEveryoneText, false, st::defaultBoxCheckbox);
|
||||||
|
} else if (peer && peer->isChannel()) {
|
||||||
|
if (peer->isMegagroup()) {
|
||||||
|
text += qsl("\n\n") + (_singleItem ? lang(lng_delete_for_everyone_this_hint) : lng_delete_for_everyone_hint(lt_count, _ids.size()));
|
||||||
|
}
|
||||||
|
} else if (peer->isChat()) {
|
||||||
|
text += qsl("\n\n") + (_singleItem ? lang(lng_delete_for_me_chat_this_hint) : lng_delete_for_me_chat_hint(lt_count, _ids.size()));
|
||||||
|
} else {
|
||||||
|
text += qsl("\n\n") + (_singleItem ? lang(lng_delete_for_me_this_hint) : lng_delete_for_me_hint(lt_count, _ids.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_text.create(this, text, Ui::FlatLabel::InitType::Simple, st::boxLabel);
|
||||||
|
|
||||||
addButton(lang(lng_box_delete), [this] { deleteAndClear(); });
|
addButton(lang(lng_box_delete), [this] { deleteAndClear(); });
|
||||||
addButton(lang(lng_cancel), [this] { closeBox(); });
|
addButton(lang(lng_cancel), [this] { closeBox(); });
|
||||||
|
|
||||||
_text->resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
|
_text->resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
|
||||||
setDimensions(st::boxWidth, st::boxPadding.top() + _text->height() + st::boxMediumSkip + _banUser->heightNoMargins() + st::boxLittleSkip + _reportSpam->heightNoMargins() + st::boxLittleSkip + _deleteAll->heightNoMargins() + st::boxPadding.bottom());
|
auto fullHeight = st::boxPadding.top() + _text->height() + st::boxPadding.bottom();
|
||||||
|
if (_moderateFrom) {
|
||||||
|
fullHeight += st::boxMediumSkip + _banUser->heightNoMargins() + st::boxLittleSkip + _reportSpam->heightNoMargins() + st::boxLittleSkip + _deleteAll->heightNoMargins();
|
||||||
|
} else if (_forEveryone) {
|
||||||
|
fullHeight += st::boxMediumSkip + _forEveryone->heightNoMargins();
|
||||||
|
}
|
||||||
|
setDimensions(st::boxWidth, fullHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichDeleteMessageBox::resizeEvent(QResizeEvent *e) {
|
void DeleteMessagesBox::resizeEvent(QResizeEvent *e) {
|
||||||
BoxContent::resizeEvent(e);
|
BoxContent::resizeEvent(e);
|
||||||
_text->moveToLeft(st::boxPadding.left(), st::boxPadding.top());
|
_text->moveToLeft(st::boxPadding.left(), st::boxPadding.top());
|
||||||
_banUser->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip);
|
if (_moderateFrom) {
|
||||||
_reportSpam->moveToLeft(st::boxPadding.left(), _banUser->bottomNoMargins() + st::boxLittleSkip);
|
_banUser->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip);
|
||||||
_deleteAll->moveToLeft(st::boxPadding.left(), _reportSpam->bottomNoMargins() + st::boxLittleSkip);
|
_reportSpam->moveToLeft(st::boxPadding.left(), _banUser->bottomNoMargins() + st::boxLittleSkip);
|
||||||
|
_deleteAll->moveToLeft(st::boxPadding.left(), _reportSpam->bottomNoMargins() + st::boxLittleSkip);
|
||||||
|
} else if (_forEveryone) {
|
||||||
|
_forEveryone->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichDeleteMessageBox::deleteAndClear() {
|
void DeleteMessagesBox::deleteAndClear() {
|
||||||
if (_banUser->checked()) {
|
if (!App::main()) {
|
||||||
MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _from->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
|
return;
|
||||||
}
|
}
|
||||||
if (_reportSpam->checked()) {
|
|
||||||
MTP::send(MTPchannels_ReportSpam(_channel->inputChannel, _from->inputUser, MTP_vector<MTPint>(1, MTP_int(_msgId))));
|
|
||||||
}
|
|
||||||
if (_deleteAll->checked()) {
|
|
||||||
App::main()->deleteAllFromUser(_channel, _from);
|
|
||||||
}
|
|
||||||
if (auto item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId)) {
|
|
||||||
auto wasLast = (item->history()->lastMsg == item);
|
|
||||||
item->destroy();
|
|
||||||
|
|
||||||
if (_msgId > 0) {
|
if (_moderateFrom) {
|
||||||
auto forEveryone = true;
|
if (_banUser->checked()) {
|
||||||
App::main()->deleteMessages(_channel, QVector<MTPint>(1, MTP_int(_msgId)), forEveryone);
|
MTP::send(MTPchannels_KickFromChannel(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
|
||||||
} else if (wasLast) {
|
|
||||||
App::main()->checkPeerHistory(_channel);
|
|
||||||
}
|
}
|
||||||
|
if (_reportSpam->checked()) {
|
||||||
|
MTP::send(MTPchannels_ReportSpam(_moderateInChannel->inputChannel, _moderateFrom->inputUser, MTP_vector<MTPint>(1, MTP_int(_ids[0].msg))));
|
||||||
|
}
|
||||||
|
if (_deleteAll->checked()) {
|
||||||
|
App::main()->deleteAllFromUser(_moderateInChannel, _moderateFrom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_singleItem) {
|
||||||
|
App::main()->clearSelectedItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<PeerData*, QVector<MTPint>> idsByPeer;
|
||||||
|
for_const (auto fullId, _ids) {
|
||||||
|
if (auto item = App::histItemById(fullId)) {
|
||||||
|
auto history = item->history();
|
||||||
|
auto wasOnServer = (item->id > 0);
|
||||||
|
auto wasLast = (history->lastMsg == item);
|
||||||
|
item->destroy();
|
||||||
|
|
||||||
|
if (wasOnServer) {
|
||||||
|
idsByPeer[history->peer].push_back(MTP_int(fullId.msg));
|
||||||
|
} else if (wasLast) {
|
||||||
|
App::main()->checkPeerHistory(history->peer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto forEveryone = _forEveryone ? _forEveryone->checked() : false;
|
||||||
|
for (auto i = idsByPeer.cbegin(), e = idsByPeer.cend(); i != e; ++i) {
|
||||||
|
App::main()->deleteMessages(i.key(), i.value(), forEveryone);
|
||||||
}
|
}
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,9 +170,10 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RichDeleteMessageBox : public BoxContent, public RPCSender {
|
class DeleteMessagesBox : public BoxContent, public RPCSender {
|
||||||
public:
|
public:
|
||||||
RichDeleteMessageBox(QWidget*, ChannelData *channel, UserData *from, MsgId msgId);
|
DeleteMessagesBox(QWidget*, HistoryItem *item, bool suggestModerateActions);
|
||||||
|
DeleteMessagesBox(QWidget*, const SelectedItemSet &selected);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
|
@ -182,14 +183,16 @@ protected:
|
||||||
private:
|
private:
|
||||||
void deleteAndClear();
|
void deleteAndClear();
|
||||||
|
|
||||||
ChannelData *_channel;
|
QVector<FullMsgId> _ids;
|
||||||
UserData *_from;
|
bool _singleItem = false;
|
||||||
MsgId _msgId;
|
UserData *_moderateFrom = nullptr;
|
||||||
|
ChannelData *_moderateInChannel = nullptr;
|
||||||
|
|
||||||
object_ptr<Ui::FlatLabel> _text;
|
object_ptr<Ui::FlatLabel> _text = { nullptr };
|
||||||
object_ptr<Ui::Checkbox> _banUser;
|
object_ptr<Ui::Checkbox> _forEveryone = { nullptr };
|
||||||
object_ptr<Ui::Checkbox> _reportSpam;
|
object_ptr<Ui::Checkbox> _banUser = { nullptr };
|
||||||
object_ptr<Ui::Checkbox> _deleteAll;
|
object_ptr<Ui::Checkbox> _reportSpam = { nullptr };
|
||||||
|
object_ptr<Ui::Checkbox> _deleteAll = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -374,7 +374,7 @@ void MembersBox::Inner::refresh() {
|
||||||
resize(width(), st::membersMarginTop + st::noContactsHeight + st::membersMarginBottom);
|
resize(width(), st::membersMarginTop + st::noContactsHeight + st::membersMarginBottom);
|
||||||
_aboutHeight = 0;
|
_aboutHeight = 0;
|
||||||
} else {
|
} else {
|
||||||
_about.setText(st::boxTextStyle, lng_channel_only_last_shown(lt_count, _rows.size()));
|
_about.setText(st::boxLabelStyle, lng_channel_only_last_shown(lt_count, _rows.size()));
|
||||||
_aboutHeight = st::membersAboutLimitPadding.top() + _about.countHeight(_aboutWidth) + st::membersAboutLimitPadding.bottom();
|
_aboutHeight = st::membersAboutLimitPadding.top() + _about.countHeight(_aboutWidth) + st::membersAboutLimitPadding.bottom();
|
||||||
if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) {
|
if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) {
|
||||||
_aboutHeight = 0;
|
_aboutHeight = 0;
|
||||||
|
|
|
@ -148,7 +148,7 @@ StickersBox::StickersBox(QWidget*, const Stickers::Order &archivedIds)
|
||||||
: _section(Section::ArchivedPart)
|
: _section(Section::ArchivedPart)
|
||||||
, _archived(0, this, archivedIds)
|
, _archived(0, this, archivedIds)
|
||||||
, _aboutWidth(st::boxWideWidth - 2 * st::stickersReorderPadding.top())
|
, _aboutWidth(st::boxWideWidth - 2 * st::stickersReorderPadding.top())
|
||||||
, _about(st::boxTextStyle, lang(lng_stickers_packs_archived), _defaultOptions, _aboutWidth) {
|
, _about(st::boxLabelStyle, lang(lng_stickers_packs_archived), _defaultOptions, _aboutWidth) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) {
|
void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) {
|
||||||
|
|
|
@ -316,18 +316,7 @@ PeerData *getPeerForMouseAction() {
|
||||||
bool hideWindowNoQuit() {
|
bool hideWindowNoQuit() {
|
||||||
if (!App::quitting()) {
|
if (!App::quitting()) {
|
||||||
if (auto w = App::wnd()) {
|
if (auto w = App::wnd()) {
|
||||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
w->hideNoQuit();
|
||||||
if (w->minimizeToTray()) {
|
|
||||||
Ui::showChatsList();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
|
||||||
w->closeWithoutDestroy();
|
|
||||||
w->updateIsActive(Global::OfflineBlurTimeout());
|
|
||||||
w->updateGlobalMenu();
|
|
||||||
Ui::showChatsList();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -48,6 +48,14 @@ constexpr int kSetMyActionForMs = 10000;
|
||||||
|
|
||||||
auto GlobalPinnedIndex = 0;
|
auto GlobalPinnedIndex = 0;
|
||||||
|
|
||||||
|
HistoryItem *createUnsupportedMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from) {
|
||||||
|
QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org")));
|
||||||
|
EntitiesInText entities;
|
||||||
|
textParseEntities(text, _historyTextNoMonoOptions.flags, &entities);
|
||||||
|
entities.push_front(EntityInText(EntityInTextItalic, 0, text.size()));
|
||||||
|
return HistoryMessage::create(history, msgId, flags, replyTo, viaBotId, date, from, { text, entities });
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void historyInit() {
|
void historyInit() {
|
||||||
|
@ -741,7 +749,7 @@ void Histories::clearPinned() {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) {
|
HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) {
|
||||||
MsgId msgId = 0;
|
auto msgId = MsgId(0);
|
||||||
switch (msg.type()) {
|
switch (msg.type()) {
|
||||||
case mtpc_messageEmpty: msgId = msg.c_messageEmpty().vid.v; break;
|
case mtpc_messageEmpty: msgId = msg.c_messageEmpty().vid.v; break;
|
||||||
case mtpc_message: msgId = msg.c_message().vid.v; break;
|
case mtpc_message: msgId = msg.c_message().vid.v; break;
|
||||||
|
@ -749,7 +757,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
}
|
}
|
||||||
if (!msgId) return nullptr;
|
if (!msgId) return nullptr;
|
||||||
|
|
||||||
HistoryItem *result = App::histItemById(channelId(), msgId);
|
auto result = App::histItemById(channelId(), msgId);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (!result->detached() && detachExistingItem) {
|
if (!result->detached() && detachExistingItem) {
|
||||||
result->detach();
|
result->detach();
|
||||||
|
@ -769,37 +777,42 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mtpc_message: {
|
case mtpc_message: {
|
||||||
const auto &m(msg.c_message());
|
auto &m = msg.c_message();
|
||||||
int badMedia = 0; // 1 - unsupported, 2 - empty
|
enum class MediaCheckResult {
|
||||||
|
Good,
|
||||||
|
Unsupported,
|
||||||
|
Empty,
|
||||||
|
};
|
||||||
|
auto badMedia = MediaCheckResult::Good;
|
||||||
if (m.has_media()) switch (m.vmedia.type()) {
|
if (m.has_media()) switch (m.vmedia.type()) {
|
||||||
case mtpc_messageMediaEmpty:
|
case mtpc_messageMediaEmpty:
|
||||||
case mtpc_messageMediaContact: break;
|
case mtpc_messageMediaContact: break;
|
||||||
case mtpc_messageMediaGeo:
|
case mtpc_messageMediaGeo:
|
||||||
switch (m.vmedia.c_messageMediaGeo().vgeo.type()) {
|
switch (m.vmedia.c_messageMediaGeo().vgeo.type()) {
|
||||||
case mtpc_geoPoint: break;
|
case mtpc_geoPoint: break;
|
||||||
case mtpc_geoPointEmpty: badMedia = 2; break;
|
case mtpc_geoPointEmpty: badMedia = MediaCheckResult::Empty; break;
|
||||||
default: badMedia = 1; break;
|
default: badMedia = MediaCheckResult::Unsupported; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mtpc_messageMediaVenue:
|
case mtpc_messageMediaVenue:
|
||||||
switch (m.vmedia.c_messageMediaVenue().vgeo.type()) {
|
switch (m.vmedia.c_messageMediaVenue().vgeo.type()) {
|
||||||
case mtpc_geoPoint: break;
|
case mtpc_geoPoint: break;
|
||||||
case mtpc_geoPointEmpty: badMedia = 2; break;
|
case mtpc_geoPointEmpty: badMedia = MediaCheckResult::Empty; break;
|
||||||
default: badMedia = 1; break;
|
default: badMedia = MediaCheckResult::Unsupported; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mtpc_messageMediaPhoto:
|
case mtpc_messageMediaPhoto:
|
||||||
switch (m.vmedia.c_messageMediaPhoto().vphoto.type()) {
|
switch (m.vmedia.c_messageMediaPhoto().vphoto.type()) {
|
||||||
case mtpc_photo: break;
|
case mtpc_photo: break;
|
||||||
case mtpc_photoEmpty: badMedia = 2; break;
|
case mtpc_photoEmpty: badMedia = MediaCheckResult::Empty; break;
|
||||||
default: badMedia = 1; break;
|
default: badMedia = MediaCheckResult::Unsupported; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mtpc_messageMediaDocument:
|
case mtpc_messageMediaDocument:
|
||||||
switch (m.vmedia.c_messageMediaDocument().vdocument.type()) {
|
switch (m.vmedia.c_messageMediaDocument().vdocument.type()) {
|
||||||
case mtpc_document: break;
|
case mtpc_document: break;
|
||||||
case mtpc_documentEmpty: badMedia = 2; break;
|
case mtpc_documentEmpty: badMedia = MediaCheckResult::Empty; break;
|
||||||
default: badMedia = 1; break;
|
default: badMedia = MediaCheckResult::Unsupported; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mtpc_messageMediaWebPage:
|
case mtpc_messageMediaWebPage:
|
||||||
|
@ -808,25 +821,21 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
case mtpc_webPageEmpty:
|
case mtpc_webPageEmpty:
|
||||||
case mtpc_webPagePending: break;
|
case mtpc_webPagePending: break;
|
||||||
case mtpc_webPageNotModified:
|
case mtpc_webPageNotModified:
|
||||||
default: badMedia = 1; break;
|
default: badMedia = MediaCheckResult::Unsupported; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mtpc_messageMediaGame:
|
case mtpc_messageMediaGame:
|
||||||
switch (m.vmedia.c_messageMediaGame().vgame.type()) {
|
switch (m.vmedia.c_messageMediaGame().vgame.type()) {
|
||||||
case mtpc_game: break;
|
case mtpc_game: break;
|
||||||
default: badMedia = 1; break;
|
default: badMedia = MediaCheckResult::Unsupported; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mtpc_messageMediaUnsupported:
|
case mtpc_messageMediaUnsupported:
|
||||||
default: badMedia = 1; break;
|
default: badMedia = MediaCheckResult::Unsupported; break;
|
||||||
}
|
}
|
||||||
if (badMedia == 1) {
|
if (badMedia == MediaCheckResult::Unsupported) {
|
||||||
QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org")));
|
result = createUnsupportedMessage(this, m.vid.v, m.vflags.v, m.vreply_to_msg_id.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v);
|
||||||
EntitiesInText entities;
|
} else if (badMedia == MediaCheckResult::Empty) {
|
||||||
textParseEntities(text, _historyTextNoMonoOptions.flags, &entities);
|
|
||||||
entities.push_front(EntityInText(EntityInTextItalic, 0, text.size()));
|
|
||||||
result = HistoryMessage::create(this, m.vid.v, m.vflags.v, m.vreply_to_msg_id.v, m.vvia_bot_id.v, date(m.vdate), m.vfrom_id.v, { text, entities });
|
|
||||||
} else if (badMedia) {
|
|
||||||
result = HistoryService::create(this, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, m.has_from_id() ? m.vfrom_id.v : 0);
|
result = HistoryService::create(this, m.vid.v, date(m.vdate), lang(lng_message_empty), m.vflags.v, m.has_from_id() ? m.vfrom_id.v : 0);
|
||||||
} else {
|
} else {
|
||||||
result = HistoryMessage::create(this, m);
|
result = HistoryMessage::create(this, m);
|
||||||
|
@ -834,18 +843,23 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageService: {
|
case mtpc_messageService: {
|
||||||
const auto &d(msg.c_messageService());
|
auto &m = msg.c_messageService();
|
||||||
result = HistoryService::create(this, d);
|
if (m.vaction.type() == mtpc_messageActionPhoneCall) {
|
||||||
|
auto viaBotId = 0;
|
||||||
|
result = createUnsupportedMessage(this, m.vid.v, mtpCastFlags(m.vflags.v), m.vreply_to_msg_id.v, viaBotId, date(m.vdate), m.vfrom_id.v);
|
||||||
|
} else {
|
||||||
|
result = HistoryService::create(this, m);
|
||||||
|
}
|
||||||
|
|
||||||
if (applyServiceAction) {
|
if (applyServiceAction) {
|
||||||
const auto &action(d.vaction);
|
auto &action = m.vaction;
|
||||||
switch (d.vaction.type()) {
|
switch (action.type()) {
|
||||||
case mtpc_messageActionChatAddUser: {
|
case mtpc_messageActionChatAddUser: {
|
||||||
const auto &d(action.c_messageActionChatAddUser());
|
auto &d = action.c_messageActionChatAddUser();
|
||||||
if (peer->isMegagroup()) {
|
if (peer->isMegagroup()) {
|
||||||
const auto &v(d.vusers.c_vector().v);
|
auto &v = d.vusers.c_vector().v;
|
||||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
for (auto i = 0, l = v.size(); i != l; ++i) {
|
||||||
if (UserData *user = App::userLoaded(peerFromUser(v.at(i)))) {
|
if (auto user = App::userLoaded(peerFromUser(v[i]))) {
|
||||||
if (peer->asChannel()->mgInfo->lastParticipants.indexOf(user) < 0) {
|
if (peer->asChannel()->mgInfo->lastParticipants.indexOf(user) < 0) {
|
||||||
peer->asChannel()->mgInfo->lastParticipants.push_front(user);
|
peer->asChannel()->mgInfo->lastParticipants.push_front(user);
|
||||||
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
|
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
|
||||||
|
@ -863,7 +877,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageActionChatJoinedByLink: {
|
case mtpc_messageActionChatJoinedByLink: {
|
||||||
const auto &d(action.c_messageActionChatJoinedByLink());
|
auto &d = action.c_messageActionChatJoinedByLink();
|
||||||
if (peer->isMegagroup()) {
|
if (peer->isMegagroup()) {
|
||||||
if (result->from()->isUser()) {
|
if (result->from()->isUser()) {
|
||||||
if (peer->asChannel()->mgInfo->lastParticipants.indexOf(result->from()->asUser()) < 0) {
|
if (peer->asChannel()->mgInfo->lastParticipants.indexOf(result->from()->asUser()) < 0) {
|
||||||
|
@ -881,13 +895,13 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageActionChatDeletePhoto: {
|
case mtpc_messageActionChatDeletePhoto: {
|
||||||
ChatData *chat = peer->asChat();
|
auto chat = peer->asChat();
|
||||||
if (chat) chat->setPhoto(MTP_chatPhotoEmpty());
|
if (chat) chat->setPhoto(MTP_chatPhotoEmpty());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageActionChatDeleteUser: {
|
case mtpc_messageActionChatDeleteUser: {
|
||||||
const auto &d(action.c_messageActionChatDeleteUser());
|
auto &d = action.c_messageActionChatDeleteUser();
|
||||||
PeerId uid = peerFromUser(d.vuser_id);
|
auto uid = peerFromUser(d.vuser_id);
|
||||||
if (lastKeyboardFrom == uid) {
|
if (lastKeyboardFrom == uid) {
|
||||||
clearLastKeyboard();
|
clearLastKeyboard();
|
||||||
}
|
}
|
||||||
|
@ -952,7 +966,7 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageActionChatEditTitle: {
|
case mtpc_messageActionChatEditTitle: {
|
||||||
auto &d(action.c_messageActionChatEditTitle());
|
auto &d = action.c_messageActionChatEditTitle();
|
||||||
if (auto chat = peer->asChat()) {
|
if (auto chat = peer->asChat()) {
|
||||||
chat->setName(qs(d.vtitle));
|
chat->setName(qs(d.vtitle));
|
||||||
}
|
}
|
||||||
|
@ -961,18 +975,18 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction,
|
||||||
case mtpc_messageActionChatMigrateTo: {
|
case mtpc_messageActionChatMigrateTo: {
|
||||||
peer->asChat()->flags |= MTPDchat::Flag::f_deactivated;
|
peer->asChat()->flags |= MTPDchat::Flag::f_deactivated;
|
||||||
|
|
||||||
//const auto &d(action.c_messageActionChatMigrateTo());
|
//auto &d = action.c_messageActionChatMigrateTo();
|
||||||
//PeerData *channel = App::channelLoaded(d.vchannel_id.v);
|
//auto channel = App::channelLoaded(d.vchannel_id.v);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageActionChannelMigrateFrom: {
|
case mtpc_messageActionChannelMigrateFrom: {
|
||||||
//const auto &d(action.c_messageActionChannelMigrateFrom());
|
//auto &d = action.c_messageActionChannelMigrateFrom();
|
||||||
//PeerData *chat = App::chatLoaded(d.vchat_id.v);
|
//auto chat = App::chatLoaded(d.vchat_id.v);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messageActionPinMessage: {
|
case mtpc_messageActionPinMessage: {
|
||||||
if (d.has_reply_to_msg_id() && result && result->history()->peer->isMegagroup()) {
|
if (m.has_reply_to_msg_id() && result && result->history()->peer->isMegagroup()) {
|
||||||
result->history()->peer->asChannel()->mgInfo->pinnedMsgId = d.vreply_to_msg_id.v;
|
result->history()->peer->asChannel()->mgInfo->pinnedMsgId = m.vreply_to_msg_id.v;
|
||||||
if (App::main()) emit App::main()->peerUpdated(result->history()->peer);
|
if (App::main()) emit App::main()->peerUpdated(result->history()->peer);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -772,6 +772,18 @@ bool HistoryItem::canEdit(const QDateTime &cur) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HistoryItem::canDeleteForEveryone(const QDateTime &cur) const {
|
||||||
|
auto messageToMyself = (peerToUser(_history->peer->id) == MTP::authedId());
|
||||||
|
auto messageTooOld = messageToMyself ? false : (date.secsTo(cur) >= Global::EditTimeLimit());
|
||||||
|
if (id < 0 || messageToMyself || messageTooOld) return false;
|
||||||
|
if (history()->peer->isChannel()) return false;
|
||||||
|
|
||||||
|
if (auto msg = toHistoryMessage()) {
|
||||||
|
return !isPost() && out();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool HistoryItem::unread() const {
|
bool HistoryItem::unread() const {
|
||||||
// Messages from myself are always read.
|
// Messages from myself are always read.
|
||||||
if (history()->peer->isSelf()) return false;
|
if (history()->peer->isSelf()) return false;
|
||||||
|
|
|
@ -704,6 +704,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool canEdit(const QDateTime &cur) const;
|
bool canEdit(const QDateTime &cur) const;
|
||||||
|
bool canDeleteForEveryone(const QDateTime &cur) const;
|
||||||
|
|
||||||
bool suggestBanReportDeleteAll() const {
|
bool suggestBanReportDeleteAll() const {
|
||||||
ChannelData *channel = history()->peer->asChannel();
|
ChannelData *channel = history()->peer->asChannel();
|
||||||
|
|
|
@ -2848,7 +2848,7 @@ void HistoryHider::resizeEvent(QResizeEvent *e) {
|
||||||
_send->show();
|
_send->show();
|
||||||
_cancel->show();
|
_cancel->show();
|
||||||
}
|
}
|
||||||
h += st::boxTopMargin + qMax(st::boxTextFont->height, st::boxTextStyle.lineHeight) + st::boxButtonPadding.top() + _send->height() + st::boxButtonPadding.bottom();
|
h += st::boxTopMargin + qMax(st::boxTextFont->height, st::boxLabelStyle.lineHeight) + st::boxButtonPadding.top() + _send->height() + st::boxButtonPadding.bottom();
|
||||||
} else {
|
} else {
|
||||||
h += st::historyForwardChooseFont->height;
|
h += st::historyForwardChooseFont->height;
|
||||||
_send->hide();
|
_send->hide();
|
||||||
|
@ -2862,7 +2862,7 @@ void HistoryHider::resizeEvent(QResizeEvent *e) {
|
||||||
bool HistoryHider::offerPeer(PeerId peer) {
|
bool HistoryHider::offerPeer(PeerId peer) {
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
_offered = nullptr;
|
_offered = nullptr;
|
||||||
_toText.setText(st::boxTextStyle, QString());
|
_toText.setText(st::boxLabelStyle, QString());
|
||||||
_toTextWidth = 0;
|
_toTextWidth = 0;
|
||||||
resizeEvent(nullptr);
|
resizeEvent(nullptr);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2902,7 +2902,7 @@ bool HistoryHider::offerPeer(PeerId peer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_toText.setText(st::boxTextStyle, phrase, _textNameOptions);
|
_toText.setText(st::boxLabelStyle, phrase, _textNameOptions);
|
||||||
_toTextWidth = _toText.maxWidth();
|
_toTextWidth = _toText.maxWidth();
|
||||||
if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right()) {
|
if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right()) {
|
||||||
_toTextWidth = _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right();
|
_toTextWidth = _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right();
|
||||||
|
@ -8352,8 +8352,13 @@ void HistoryWidget::confirmDeleteContextItem() {
|
||||||
auto item = App::contextItem();
|
auto item = App::contextItem();
|
||||||
if (!item || item->type() != HistoryItemMsg) return;
|
if (!item || item->type() != HistoryItemMsg) return;
|
||||||
|
|
||||||
auto message = item->toHistoryMessage();
|
if (auto message = item->toHistoryMessage()) {
|
||||||
App::main()->deleteLayer((message && message->uploading()) ? -2 : -1);
|
if (message->uploading()) {
|
||||||
|
App::main()->cancelUploadLayer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
App::main()->deleteLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::confirmDeleteSelectedItems() {
|
void HistoryWidget::confirmDeleteSelectedItems() {
|
||||||
|
|
|
@ -660,43 +660,39 @@ void MainWidget::forwardLayer(int forwardSelected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::deleteLayer(int selectedCount) {
|
void MainWidget::deleteLayer(int selectedCount) {
|
||||||
if (selectedCount == -1 && !_overview) {
|
if (selectedCount) {
|
||||||
if (auto item = App::contextItem()) {
|
auto forDelete = true;
|
||||||
if (item->suggestBanReportDeleteAll()) {
|
SelectedItemSet selected;
|
||||||
Ui::show(Box<RichDeleteMessageBox>(item->history()->peer->asChannel(), item->from()->asUser(), item->id));
|
if (_overview) {
|
||||||
return;
|
_overview->fillSelectedItems(selected, forDelete);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto text = (selectedCount < 0) ? lang(selectedCount < -1 ? lng_selected_cancel_sure_this : lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, selectedCount);
|
|
||||||
auto confirmText = lang((selectedCount < -1) ? lng_selected_upload_stop : lng_box_delete);
|
|
||||||
auto cancelText = lang((selectedCount < -1) ? lng_continue : lng_cancel);
|
|
||||||
if (selectedCount < -1) {
|
|
||||||
if (auto item = App::contextItem()) {
|
|
||||||
App::uploader()->pause(item->fullId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ui::show(Box<ConfirmBox>(text, confirmText, cancelText, base::lambda_guarded(this, [this, selectedCount] {
|
|
||||||
if (selectedCount < 0) {
|
|
||||||
if (_overview) {
|
|
||||||
_overview->deleteContextItem(false);
|
|
||||||
} else {
|
|
||||||
_history->deleteContextItem(false);
|
|
||||||
}
|
|
||||||
if (selectedCount < -1) {
|
|
||||||
App::uploader()->unpause();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (_overview) {
|
_history->fillSelectedItems(selected, forDelete);
|
||||||
_overview->deleteSelectedItems(false);
|
|
||||||
} else {
|
|
||||||
_history->deleteSelectedItems(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}), base::lambda_guarded(this, [selectedCount] {
|
if (!selected.isEmpty()) {
|
||||||
if (selectedCount < -1) {
|
Ui::show(Box<DeleteMessagesBox>(selected));
|
||||||
App::uploader()->unpause();
|
|
||||||
}
|
}
|
||||||
|
} else if (auto item = App::contextItem()) {
|
||||||
|
auto suggestModerateActions = !_overview;
|
||||||
|
Ui::show(Box<DeleteMessagesBox>(item, suggestModerateActions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::cancelUploadLayer() {
|
||||||
|
auto item = App::contextItem();
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
App::uploader()->pause(item->fullId());
|
||||||
|
Ui::show(Box<ConfirmBox>(lang(lng_selected_cancel_sure_this), lang(lng_selected_upload_stop), lang(lng_continue), base::lambda_guarded(this, [this] {
|
||||||
|
if (_overview) {
|
||||||
|
_overview->deleteContextItem(false);
|
||||||
|
} else {
|
||||||
|
_history->deleteContextItem(false);
|
||||||
|
}
|
||||||
|
App::uploader()->unpause();
|
||||||
|
}), base::lambda_guarded(this, [] {
|
||||||
|
App::uploader()->unpause();
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,8 @@ public:
|
||||||
int32 dlgsWidth() const;
|
int32 dlgsWidth() const;
|
||||||
|
|
||||||
void forwardLayer(int forwardSelected = 0); // -1 - send paths
|
void forwardLayer(int forwardSelected = 0); // -1 - send paths
|
||||||
void deleteLayer(int selectedCount = -1); // -1 - context item, else selected, -2 - cancel upload
|
void deleteLayer(int selectedCount = 0); // 0 - context item
|
||||||
|
void cancelUploadLayer();
|
||||||
void shareContactLayer(UserData *contact);
|
void shareContactLayer(UserData *contact);
|
||||||
void shareUrlLayer(const QString &url, const QString &text);
|
void shareUrlLayer(const QString &url, const QString &text);
|
||||||
void inlineSwitchLayer(const QString &botAndQuery);
|
void inlineSwitchLayer(const QString &botAndQuery);
|
||||||
|
|
|
@ -204,11 +204,7 @@ void MainWindow::firstShow() {
|
||||||
psFirstShow();
|
psFirstShow();
|
||||||
updateTrayMenu();
|
updateTrayMenu();
|
||||||
|
|
||||||
_mediaView = new MediaView();
|
createMediaView();
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *MainWindow::filedialogParent() {
|
|
||||||
return (_mediaView && _mediaView->isVisible()) ? (QWidget*)_mediaView : (QWidget*)this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::clearWidgets() {
|
void MainWindow::clearWidgets() {
|
||||||
|
@ -600,30 +596,6 @@ void MainWindow::layerHidden() {
|
||||||
checkHistoryActivation();
|
checkHistoryActivation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onReActivate() {
|
|
||||||
if (auto w = App::wnd()) {
|
|
||||||
if (auto f = QApplication::focusWidget()) {
|
|
||||||
f->clearFocus();
|
|
||||||
}
|
|
||||||
w->windowHandle()->requestActivate();
|
|
||||||
w->activate();
|
|
||||||
if (auto f = QApplication::focusWidget()) {
|
|
||||||
f->clearFocus();
|
|
||||||
}
|
|
||||||
w->setInnerFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::hideMediaview() {
|
|
||||||
if (_mediaView && !_mediaView->isHidden()) {
|
|
||||||
_mediaView->hide();
|
|
||||||
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
|
||||||
onReActivate();
|
|
||||||
QTimer::singleShot(200, this, SLOT(onReActivate()));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::contentOverlapped(const QRect &globalRect) {
|
bool MainWindow::contentOverlapped(const QRect &globalRect) {
|
||||||
if (_main && _main->contentOverlapped(globalRect)) return true;
|
if (_main && _main->contentOverlapped(globalRect)) return true;
|
||||||
if (_layerBg && _layerBg->contentOverlapped(globalRect)) return true;
|
if (_layerBg && _layerBg->contentOverlapped(globalRect)) return true;
|
||||||
|
@ -712,21 +684,6 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
|
||||||
return Platform::MainWindow::eventFilter(obj, e);
|
return Platform::MainWindow::eventFilter(obj, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::minimizeToTray() {
|
|
||||||
if (App::quitting() || !psHasTrayIcon()) return false;
|
|
||||||
|
|
||||||
closeWithoutDestroy();
|
|
||||||
if (cPlatform() == dbipWindows && trayIcon && !cSeenTrayTooltip()) {
|
|
||||||
trayIcon->showMessage(str_const_toString(AppName), lang(lng_tray_icon_text), QSystemTrayIcon::Information, 10000);
|
|
||||||
cSetSeenTrayTooltip(true);
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
updateIsActive(Global::OfflineBlurTimeout());
|
|
||||||
updateTrayMenu();
|
|
||||||
updateGlobalMenu();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::updateTrayMenu(bool force) {
|
void MainWindow::updateTrayMenu(bool force) {
|
||||||
if (!trayIconMenu || (cPlatform() == dbipWindows && !force)) return;
|
if (!trayIconMenu || (cPlatform() == dbipWindows && !force)) return;
|
||||||
|
|
||||||
|
@ -1450,7 +1407,6 @@ MainWindow::~MainWindow() {
|
||||||
_clearManager->stop();
|
_clearManager->stop();
|
||||||
_clearManager = nullptr;
|
_clearManager = nullptr;
|
||||||
}
|
}
|
||||||
delete _mediaView;
|
|
||||||
delete trayIcon;
|
delete trayIcon;
|
||||||
delete trayIconMenu;
|
delete trayIconMenu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,6 @@ public:
|
||||||
|
|
||||||
void firstShow();
|
void firstShow();
|
||||||
|
|
||||||
QWidget *filedialogParent();
|
|
||||||
|
|
||||||
void inactivePress(bool inactive);
|
void inactivePress(bool inactive);
|
||||||
bool inactivePress() const;
|
bool inactivePress() const;
|
||||||
|
|
||||||
|
@ -142,7 +140,6 @@ public:
|
||||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||||
|
|
||||||
bool isActive(bool cached = true) const;
|
bool isActive(bool cached = true) const;
|
||||||
void hideMediaview();
|
|
||||||
|
|
||||||
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
|
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
|
||||||
|
|
||||||
|
@ -184,7 +181,6 @@ public slots:
|
||||||
|
|
||||||
void quitFromTray();
|
void quitFromTray();
|
||||||
void showFromTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown);
|
void showFromTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown);
|
||||||
bool minimizeToTray();
|
|
||||||
void toggleTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown);
|
void toggleTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown);
|
||||||
void toggleDisplayNotifyFromTray();
|
void toggleDisplayNotifyFromTray();
|
||||||
|
|
||||||
|
@ -202,8 +198,6 @@ public slots:
|
||||||
void onLogout();
|
void onLogout();
|
||||||
void updateGlobalMenu(); // for OS X top menu
|
void updateGlobalMenu(); // for OS X top menu
|
||||||
|
|
||||||
void onReActivate();
|
|
||||||
|
|
||||||
void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
|
void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -283,8 +277,6 @@ private:
|
||||||
using NotifyWhenAlerts = QMap<History*, NotifyWhenAlert>;
|
using NotifyWhenAlerts = QMap<History*, NotifyWhenAlert>;
|
||||||
NotifyWhenAlerts _notifyWhenAlerts;
|
NotifyWhenAlerts _notifyWhenAlerts;
|
||||||
|
|
||||||
MediaView *_mediaView = nullptr;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreLaunchWindow : public TWidget {
|
class PreLaunchWindow : public TWidget {
|
||||||
|
|
|
@ -200,7 +200,7 @@ mediaviewCaptionRadius: 2px;
|
||||||
|
|
||||||
themePreviewSize: size(903px, 584px);
|
themePreviewSize: size(903px, 584px);
|
||||||
themePreviewBg: windowBg;
|
themePreviewBg: windowBg;
|
||||||
themePreviewOverlayOpacity: 0.7;
|
themePreviewOverlayOpacity: 0.8;
|
||||||
themePreviewMargin: margins(36px, 52px, 36px, 88px);
|
themePreviewMargin: margins(36px, 52px, 36px, 88px);
|
||||||
themePreviewTitleTop: 14px;
|
themePreviewTitleTop: 14px;
|
||||||
themePreviewTitleFg: windowBoldFg;
|
themePreviewTitleFg: windowBoldFg;
|
||||||
|
|
|
@ -67,7 +67,7 @@ bool typeHasMediaOverview(MediaOverviewType type) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MediaView::MediaView() : TWidget(App::wnd())
|
MediaView::MediaView(QWidget*) : TWidget(nullptr)
|
||||||
, _animStarted(getms())
|
, _animStarted(getms())
|
||||||
, _docDownload(this, lang(lng_media_download), st::mediaviewFileLink)
|
, _docDownload(this, lang(lng_media_download), st::mediaviewFileLink)
|
||||||
, _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink)
|
, _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink)
|
||||||
|
@ -75,7 +75,8 @@ MediaView::MediaView() : TWidget(App::wnd())
|
||||||
, _radial(animation(this, &MediaView::step_radial))
|
, _radial(animation(this, &MediaView::step_radial))
|
||||||
, _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
|
, _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
|
||||||
, _a_state(animation(this, &MediaView::step_state))
|
, _a_state(animation(this, &MediaView::step_state))
|
||||||
, _dropdown(this, st::mediaviewDropdownMenu) {
|
, _dropdown(this, st::mediaviewDropdownMenu)
|
||||||
|
, _dropdownShowTimer(this) {
|
||||||
TextCustomTagsMap custom;
|
TextCustomTagsMap custom;
|
||||||
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
|
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
|
||||||
_saveMsgText.setRichText(st::mediaviewSaveMsgStyle, lang(lng_mediaview_saved), _textDlgOptions, custom);
|
_saveMsgText.setRichText(st::mediaviewSaveMsgStyle, lang(lng_mediaview_saved), _textDlgOptions, custom);
|
||||||
|
@ -121,6 +122,8 @@ MediaView::MediaView() : TWidget(App::wnd())
|
||||||
connect(_docCancel, SIGNAL(clicked()), this, SLOT(onSaveCancel()));
|
connect(_docCancel, SIGNAL(clicked()), this, SLOT(onSaveCancel()));
|
||||||
|
|
||||||
_dropdown->setHiddenCallback([this] { dropdownHidden(); });
|
_dropdown->setHiddenCallback([this] { dropdownHidden(); });
|
||||||
|
_dropdownShowTimer->setSingleShot(true);
|
||||||
|
connect(_dropdownShowTimer, SIGNAL(timeout()), this, SLOT(onDropdown()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::moveToScreen() {
|
void MediaView::moveToScreen() {
|
||||||
|
@ -1333,8 +1336,9 @@ void MediaView::updateThemePreviewGeometry() {
|
||||||
auto previewRect = QRect((width() - st::themePreviewSize.width()) / 2, (height() - st::themePreviewSize.height()) / 2, st::themePreviewSize.width(), st::themePreviewSize.height());
|
auto previewRect = QRect((width() - st::themePreviewSize.width()) / 2, (height() - st::themePreviewSize.height()) / 2, st::themePreviewSize.width(), st::themePreviewSize.height());
|
||||||
_themePreviewRect = previewRect.marginsAdded(st::themePreviewMargin);
|
_themePreviewRect = previewRect.marginsAdded(st::themePreviewMargin);
|
||||||
if (_themeApply) {
|
if (_themeApply) {
|
||||||
auto right = width() - _themePreviewRect.x() - _themePreviewRect.width() + st::themePreviewMargin.right();
|
auto right = qMax(width() - _themePreviewRect.x() - _themePreviewRect.width(), 0) + st::themePreviewMargin.right();
|
||||||
_themeApply->moveToRight(right, _themePreviewRect.y() + _themePreviewRect.height() - st::themePreviewMargin.bottom() + (st::themePreviewMargin.bottom() - _themeApply->height()) / 2);
|
auto bottom = qMin(height(), _themePreviewRect.y() + _themePreviewRect.height());
|
||||||
|
_themeApply->moveToRight(right, bottom - st::themePreviewMargin.bottom() + (st::themePreviewMargin.bottom() - _themeApply->height()) / 2);
|
||||||
right += _themeApply->width() + st::themePreviewButtonsSkip;
|
right += _themeApply->width() + st::themePreviewButtonsSkip;
|
||||||
_themeCancel->moveToRight(right, _themeApply->y());
|
_themeCancel->moveToRight(right, _themeApply->y());
|
||||||
}
|
}
|
||||||
|
@ -2370,7 +2374,9 @@ bool MediaView::updateOverState(OverState newState) {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (_over != newState) {
|
if (_over != newState) {
|
||||||
if (newState == OverMore && !_ignoringDropdown) {
|
if (newState == OverMore && !_ignoringDropdown) {
|
||||||
QTimer::singleShot(0, this, SLOT(onDropdown()));
|
_dropdownShowTimer->start(0);
|
||||||
|
} else {
|
||||||
|
_dropdownShowTimer->stop();
|
||||||
}
|
}
|
||||||
updateOverRect(_over);
|
updateOverRect(_over);
|
||||||
updateOverRect(newState);
|
updateOverRect(newState);
|
||||||
|
@ -2393,7 +2399,7 @@ bool MediaView::updateOverState(OverState newState) {
|
||||||
if (i != _animOpacities.end()) {
|
if (i != _animOpacities.end()) {
|
||||||
i->start(1);
|
i->start(1);
|
||||||
} else {
|
} else {
|
||||||
_animOpacities.insert(_over, anim::value());
|
_animOpacities.insert(_over, anim::value(0, 1));
|
||||||
}
|
}
|
||||||
if (!_a_state.animating()) _a_state.start();
|
if (!_a_state.animating()) _a_state.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ class MediaView : public TWidget, private base::Subscriber, public RPCSender, pu
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MediaView();
|
MediaView(QWidget*);
|
||||||
|
|
||||||
void setVisible(bool visible) override;
|
void setVisible(bool visible) override;
|
||||||
|
|
||||||
|
@ -330,6 +330,7 @@ private:
|
||||||
|
|
||||||
Ui::PopupMenu *_menu = nullptr;
|
Ui::PopupMenu *_menu = nullptr;
|
||||||
object_ptr<Ui::DropdownMenu> _dropdown;
|
object_ptr<Ui::DropdownMenu> _dropdown;
|
||||||
|
object_ptr<QTimer> _dropdownShowTimer;
|
||||||
|
|
||||||
struct ActionData {
|
struct ActionData {
|
||||||
QString text;
|
QString text;
|
||||||
|
|
|
@ -2276,16 +2276,21 @@ void OverviewWidget::confirmDeleteContextItem() {
|
||||||
auto item = App::contextItem();
|
auto item = App::contextItem();
|
||||||
if (!item || item->type() != HistoryItemMsg) return;
|
if (!item || item->type() != HistoryItemMsg) return;
|
||||||
|
|
||||||
auto message = item->toHistoryMessage();
|
if (auto message = item->toHistoryMessage()) {
|
||||||
App::main()->deleteLayer((message && message->uploading()) ? -2 : -1);
|
if (message->uploading()) {
|
||||||
|
App::main()->cancelUploadLayer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
App::main()->deleteLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::confirmDeleteSelectedItems() {
|
void OverviewWidget::confirmDeleteSelectedItems() {
|
||||||
SelectedItemSet sel;
|
SelectedItemSet selected;
|
||||||
_inner->fillSelectedItems(sel);
|
_inner->fillSelectedItems(selected);
|
||||||
if (sel.isEmpty()) return;
|
if (selected.isEmpty()) return;
|
||||||
|
|
||||||
App::main()->deleteLayer(sel.size());
|
App::main()->deleteLayer(selected.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::deleteContextItem(bool forEveryone) {
|
void OverviewWidget::deleteContextItem(bool forEveryone) {
|
||||||
|
|
|
@ -51,8 +51,6 @@ public:
|
||||||
|
|
||||||
virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
|
virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
|
||||||
|
|
||||||
void closeWithoutDestroy() override;
|
|
||||||
|
|
||||||
int getCustomTitleHeight() const {
|
int getCustomTitleHeight() const {
|
||||||
return _customTitleHeight;
|
return _customTitleHeight;
|
||||||
}
|
}
|
||||||
|
@ -103,6 +101,8 @@ protected:
|
||||||
|
|
||||||
QTimer psUpdatedPositionTimer;
|
QTimer psUpdatedPositionTimer;
|
||||||
|
|
||||||
|
void closeWithoutDestroy() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createGlobalMenu();
|
void createGlobalMenu();
|
||||||
void updateTitleCounter();
|
void updateTitleCounter();
|
||||||
|
|
|
@ -927,7 +927,7 @@ void PhotoCancelClickHandler::onClickImpl() const {
|
||||||
if (auto media = item->getMedia()) {
|
if (auto media = item->getMedia()) {
|
||||||
if (media->type() == MediaTypePhoto && static_cast<HistoryPhoto*>(media)->photo() == data) {
|
if (media->type() == MediaTypePhoto && static_cast<HistoryPhoto*>(media)->photo() == data) {
|
||||||
App::contextItem(item);
|
App::contextItem(item);
|
||||||
App::main()->deleteLayer(-2);
|
App::main()->cancelUploadLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1240,7 +1240,7 @@ void DocumentCancelClickHandler::onClickImpl() const {
|
||||||
if (auto media = item->getMedia()) {
|
if (auto media = item->getMedia()) {
|
||||||
if (media->getDocument() == data) {
|
if (media->getDocument() == data) {
|
||||||
App::contextItem(item);
|
App::contextItem(item);
|
||||||
App::main()->deleteLayer(-2);
|
App::main()->cancelUploadLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,13 @@ public:
|
||||||
|
|
||||||
Radiobuttons radiobuttons;
|
Radiobuttons radiobuttons;
|
||||||
|
|
||||||
|
TextParseOptions _checkboxOptions = {
|
||||||
|
TextParseMultiline, // flags
|
||||||
|
0, // maxw
|
||||||
|
0, // maxh
|
||||||
|
Qt::LayoutDirectionAuto, // dir
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void RadiobuttonGroup::remove(Radiobutton * const &radio) {
|
void RadiobuttonGroup::remove(Radiobutton * const &radio) {
|
||||||
|
@ -90,17 +97,11 @@ void RadiobuttonGroup::remove(Radiobutton * const &radio) {
|
||||||
|
|
||||||
Checkbox::Checkbox(QWidget *parent, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple)
|
Checkbox::Checkbox(QWidget *parent, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple)
|
||||||
, _st(st)
|
, _st(st)
|
||||||
, _text(text)
|
, _text(_st.style, text, _checkboxOptions)
|
||||||
, _fullText(text)
|
|
||||||
, _textWidth(st.font->width(text))
|
|
||||||
, _checked(checked) {
|
, _checked(checked) {
|
||||||
if (_st.width <= 0) {
|
if (_st.width <= 0) {
|
||||||
resizeToWidth(_textWidth - _st.width);
|
resizeToWidth(_text.maxWidth() - _st.width);
|
||||||
} else {
|
} else {
|
||||||
if (_st.width < _st.textPosition.x() + _textWidth + (_st.textPosition.x() - _st.diameter)) {
|
|
||||||
_text = _st.font->elided(_fullText, qMax(_st.width - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1));
|
|
||||||
_textWidth = _st.font->width(_text);
|
|
||||||
}
|
|
||||||
resizeToWidth(_st.width);
|
resizeToWidth(_st.width);
|
||||||
}
|
}
|
||||||
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
|
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
|
||||||
|
@ -129,7 +130,7 @@ void Checkbox::finishAnimations() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Checkbox::naturalWidth() const {
|
int Checkbox::naturalWidth() const {
|
||||||
return _st.textPosition.x() + _st.font->width(_fullText);
|
return _st.textPosition.x() + _text.maxWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checkbox::paintEvent(QPaintEvent *e) {
|
void Checkbox::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -157,9 +158,10 @@ void Checkbox::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
if (_checkRect.contains(e->rect())) return;
|
if (_checkRect.contains(e->rect())) return;
|
||||||
|
|
||||||
|
auto textWidth = qMax(width() - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1);
|
||||||
|
|
||||||
p.setPen(_st.textFg);
|
p.setPen(_st.textFg);
|
||||||
p.setFont(_st.font);
|
_text.drawLeftElided(p, _st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), textWidth, width());
|
||||||
p.drawTextLeft(_st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), width(), _text, _textWidth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checkbox::onClicked() {
|
void Checkbox::onClicked() {
|
||||||
|
@ -195,19 +197,13 @@ QPoint Checkbox::prepareRippleStartPosition() const {
|
||||||
|
|
||||||
Radiobutton::Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple)
|
Radiobutton::Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::Checkbox &st) : RippleButton(parent, st.ripple)
|
||||||
, _st(st)
|
, _st(st)
|
||||||
, _text(text)
|
, _text(_st.style, text, _checkboxOptions)
|
||||||
, _fullText(text)
|
|
||||||
, _textWidth(st.font->width(text))
|
|
||||||
, _checked(checked)
|
, _checked(checked)
|
||||||
, _group(radiobuttons.reg(group))
|
, _group(radiobuttons.reg(group))
|
||||||
, _value(value) {
|
, _value(value) {
|
||||||
if (_st.width <= 0) {
|
if (_st.width <= 0) {
|
||||||
resizeToWidth(_textWidth - _st.width);
|
resizeToWidth(_text.maxWidth() - _st.width);
|
||||||
} else {
|
} else {
|
||||||
if (_st.width < _st.textPosition.x() + _textWidth + (_st.textPosition.x() - _st.diameter)) {
|
|
||||||
_text = _st.font->elided(_fullText, qMax(_st.width - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1));
|
|
||||||
_textWidth = _st.font->width(_text);
|
|
||||||
}
|
|
||||||
resizeToWidth(_st.width);
|
resizeToWidth(_st.width);
|
||||||
}
|
}
|
||||||
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
|
_checkRect = myrtlrect(_st.margin.left(), _st.margin.top(), _st.diameter, _st.diameter);
|
||||||
|
@ -235,7 +231,7 @@ void Radiobutton::setChecked(bool checked) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Radiobutton::naturalWidth() const {
|
int Radiobutton::naturalWidth() const {
|
||||||
return _st.textPosition.x() + _st.font->width(_fullText);
|
return _st.textPosition.x() + _text.maxWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radiobutton::paintEvent(QPaintEvent *e) {
|
void Radiobutton::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -278,9 +274,10 @@ void Radiobutton::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
if (_checkRect.contains(e->rect())) return;
|
if (_checkRect.contains(e->rect())) return;
|
||||||
|
|
||||||
|
auto textWidth = qMax(width() - (_st.textPosition.x() + (_st.textPosition.x() - _st.diameter)), 1);
|
||||||
|
|
||||||
p.setPen(_st.textFg);
|
p.setPen(_st.textFg);
|
||||||
p.setFont(_st.font);
|
_text.drawLeftElided(p, _st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), textWidth, width());
|
||||||
p.drawTextLeft(_st.margin.left() + _st.textPosition.x(), _st.margin.top() + _st.textPosition.y(), width(), _text, _textWidth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radiobutton::onClicked() {
|
void Radiobutton::onClicked() {
|
||||||
|
|
|
@ -63,8 +63,7 @@ signals:
|
||||||
private:
|
private:
|
||||||
const style::Checkbox &_st;
|
const style::Checkbox &_st;
|
||||||
|
|
||||||
QString _text, _fullText;
|
Text _text;
|
||||||
int32 _textWidth;
|
|
||||||
QRect _checkRect;
|
QRect _checkRect;
|
||||||
|
|
||||||
bool _checked;
|
bool _checked;
|
||||||
|
@ -76,12 +75,12 @@ class Radiobutton : public RippleButton {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked = false, const style::Checkbox &st = st::defaultCheckbox);
|
Radiobutton(QWidget *parent, const QString &group, int value, const QString &text, bool checked = false, const style::Checkbox &st = st::defaultCheckbox);
|
||||||
|
|
||||||
bool checked() const;
|
bool checked() const;
|
||||||
void setChecked(bool checked);
|
void setChecked(bool checked);
|
||||||
|
|
||||||
int32 val() const {
|
int val() const {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,15 +111,14 @@ private:
|
||||||
|
|
||||||
const style::Checkbox &_st;
|
const style::Checkbox &_st;
|
||||||
|
|
||||||
QString _text, _fullText;
|
Text _text;
|
||||||
int32 _textWidth;
|
|
||||||
QRect _checkRect;
|
QRect _checkRect;
|
||||||
|
|
||||||
bool _checked;
|
bool _checked;
|
||||||
Animation _a_checked;
|
Animation _a_checked;
|
||||||
|
|
||||||
void *_group;
|
void *_group;
|
||||||
int32 _value;
|
int _value;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,8 @@ bool InnerDropdown::eventFilter(QObject *obj, QEvent *e) {
|
||||||
int InnerDropdown::resizeGetHeight(int newWidth) {
|
int InnerDropdown::resizeGetHeight(int newWidth) {
|
||||||
auto newHeight = _st.padding.top() + _st.scrollMargin.top() + _st.scrollMargin.bottom() + _st.padding.bottom();
|
auto newHeight = _st.padding.top() + _st.scrollMargin.top() + _st.scrollMargin.bottom() + _st.padding.bottom();
|
||||||
if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
|
if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
|
||||||
widget->resizeToWidth(newWidth - _st.padding.left() - _st.padding.right() - _st.scrollMargin.left() - _st.scrollMargin.right());
|
auto containerWidth = newWidth - _st.padding.left() - _st.padding.right() - _st.scrollMargin.left() - _st.scrollMargin.right();
|
||||||
|
widget->resizeToWidth(containerWidth);
|
||||||
newHeight += widget->height();
|
newHeight += widget->height();
|
||||||
}
|
}
|
||||||
if (_maxHeight > 0) {
|
if (_maxHeight > 0) {
|
||||||
|
@ -332,7 +333,7 @@ void InnerDropdown::Container::setVisibleTopBottom(int visibleTop, int visibleBo
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerDropdown::Container::resizeToContent() {
|
void InnerDropdown::Container::resizeToContent() {
|
||||||
auto newWidth = _st.scrollPadding.top() + _st.scrollPadding.bottom();
|
auto newWidth = _st.scrollPadding.left() + _st.scrollPadding.right();
|
||||||
auto newHeight = _st.scrollPadding.top() + _st.scrollPadding.bottom();
|
auto newHeight = _st.scrollPadding.top() + _st.scrollPadding.bottom();
|
||||||
if (auto child = static_cast<TWidget*>(children().front())) {
|
if (auto child = static_cast<TWidget*>(children().front())) {
|
||||||
newWidth += child->width();
|
newWidth += child->width();
|
||||||
|
@ -344,8 +345,8 @@ void InnerDropdown::Container::resizeToContent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int InnerDropdown::Container::resizeGetHeight(int newWidth) {
|
int InnerDropdown::Container::resizeGetHeight(int newWidth) {
|
||||||
int innerWidth = newWidth - _st.scrollPadding.left() - _st.scrollPadding.right();
|
auto innerWidth = newWidth - _st.scrollPadding.left() - _st.scrollPadding.right();
|
||||||
int result = _st.scrollPadding.top() + _st.scrollPadding.bottom();
|
auto result = _st.scrollPadding.top() + _st.scrollPadding.bottom();
|
||||||
if (auto child = static_cast<TWidget*>(children().front())) {
|
if (auto child = static_cast<TWidget*>(children().front())) {
|
||||||
child->resizeToWidth(innerWidth);
|
child->resizeToWidth(innerWidth);
|
||||||
child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top());
|
child->moveToLeft(_st.scrollPadding.left(), _st.scrollPadding.top());
|
||||||
|
|
|
@ -34,6 +34,7 @@ TextParseOptions _labelOptions = {
|
||||||
0, // maxh
|
0, // maxh
|
||||||
Qt::LayoutDirectionAuto, // dir
|
Qt::LayoutDirectionAuto, // dir
|
||||||
};
|
};
|
||||||
|
|
||||||
TextParseOptions _labelMarkedOptions = {
|
TextParseOptions _labelMarkedOptions = {
|
||||||
TextParseMultiline | TextParseRichText | TextParseLinks | TextParseHashtags | TextParseMentions | TextParseBotCommands | TextParseMono, // flags
|
TextParseMultiline | TextParseRichText | TextParseLinks | TextParseHashtags | TextParseMentions | TextParseBotCommands | TextParseMono, // flags
|
||||||
0, // maxw
|
0, // maxw
|
||||||
|
|
|
@ -109,7 +109,7 @@ Checkbox {
|
||||||
radioSkip: pixels;
|
radioSkip: pixels;
|
||||||
checkIcon: icon;
|
checkIcon: icon;
|
||||||
|
|
||||||
font: font;
|
style: TextStyle;
|
||||||
duration: int;
|
duration: int;
|
||||||
|
|
||||||
rippleAreaPosition: point;
|
rippleAreaPosition: point;
|
||||||
|
@ -641,7 +641,7 @@ defaultCheckbox: Checkbox {
|
||||||
checkIcon: defaultCheckboxIcon;
|
checkIcon: defaultCheckboxIcon;
|
||||||
radioSkip: 65px; // * 0.1
|
radioSkip: 65px; // * 0.1
|
||||||
|
|
||||||
font: normalFont;
|
style: defaultTextStyle;
|
||||||
duration: 120;
|
duration: 120;
|
||||||
|
|
||||||
rippleAreaSize: 38px;
|
rippleAreaSize: 38px;
|
||||||
|
|
|
@ -25,6 +25,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
#include "platform/platform_window_title.h"
|
#include "platform/platform_window_title.h"
|
||||||
#include "window/window_theme.h"
|
#include "window/window_theme.h"
|
||||||
|
#include "mediaview.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
|
@ -43,6 +45,57 @@ MainWindow::MainWindow() : QWidget()
|
||||||
subscribe(Global::RefUnreadCounterUpdate(), [this] { updateUnreadCounter(); });
|
subscribe(Global::RefUnreadCounterUpdate(), [this] { updateUnreadCounter(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MainWindow::hideNoQuit() {
|
||||||
|
if (_mediaView && !_mediaView->isHidden()) {
|
||||||
|
_mediaView->hide();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||||
|
if (minimizeToTray()) {
|
||||||
|
Ui::showChatsList();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
|
closeWithoutDestroy();
|
||||||
|
updateIsActive(Global::OfflineBlurTimeout());
|
||||||
|
updateGlobalMenu();
|
||||||
|
Ui::showChatsList();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::hideMediaview() {
|
||||||
|
if (_mediaView && !_mediaView->isHidden()) {
|
||||||
|
_mediaView->hide();
|
||||||
|
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
||||||
|
onReActivate();
|
||||||
|
QTimer::singleShot(200, this, SLOT(onReActivate()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onReActivate() {
|
||||||
|
if (auto w = App::wnd()) {
|
||||||
|
if (auto f = QApplication::focusWidget()) {
|
||||||
|
f->clearFocus();
|
||||||
|
}
|
||||||
|
w->windowHandle()->requestActivate();
|
||||||
|
w->activate();
|
||||||
|
if (auto f = QApplication::focusWidget()) {
|
||||||
|
f->clearFocus();
|
||||||
|
}
|
||||||
|
w->setInnerFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *MainWindow::filedialogParent() {
|
||||||
|
return (_mediaView && _mediaView->isVisible()) ? (QWidget*)_mediaView : (QWidget*)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createMediaView() {
|
||||||
|
_mediaView.create(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::init() {
|
void MainWindow::init() {
|
||||||
initHook();
|
initHook();
|
||||||
|
|
||||||
|
@ -197,11 +250,25 @@ void MainWindow::savePosition(Qt::WindowState state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
bool MainWindow::minimizeToTray() {
|
||||||
|
if (App::quitting() || !psHasTrayIcon()) return false;
|
||||||
|
|
||||||
|
closeWithoutDestroy();
|
||||||
|
if (cPlatform() == dbipWindows && trayIcon && !cSeenTrayTooltip()) {
|
||||||
|
trayIcon->showMessage(str_const_toString(AppName), lang(lng_tray_icon_text), QSystemTrayIcon::Information, 10000);
|
||||||
|
cSetSeenTrayTooltip(true);
|
||||||
|
Local::writeSettings();
|
||||||
|
}
|
||||||
|
updateIsActive(Global::OfflineBlurTimeout());
|
||||||
|
updateTrayMenu();
|
||||||
|
updateGlobalMenu();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeWithoutDestroy() {
|
void MainWindow::closeWithoutDestroy() {
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow() = default;
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
|
@ -22,6 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "window/window_title.h"
|
#include "window/window_title.h"
|
||||||
|
|
||||||
|
class MediaView;
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
class TitleWidget;
|
class TitleWidget;
|
||||||
|
@ -32,6 +34,9 @@ class MainWindow : public QWidget, protected base::Subscriber {
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
|
|
||||||
|
bool hideNoQuit();
|
||||||
|
void hideMediaview();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
HitTestResult hitTest(const QPoint &p) const;
|
HitTestResult hitTest(const QPoint &p) const;
|
||||||
|
|
||||||
|
@ -46,7 +51,7 @@ public:
|
||||||
return _titleText;
|
return _titleText;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void closeWithoutDestroy();
|
QWidget *filedialogParent();
|
||||||
|
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
|
|
||||||
|
@ -54,6 +59,9 @@ public:
|
||||||
return _body.data();
|
return _body.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
bool minimizeToTray();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
|
@ -71,15 +79,22 @@ protected:
|
||||||
virtual void unreadCounterChangedHook() {
|
virtual void unreadCounterChangedHook() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void closeWithoutDestroy() {
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
// This one is overriden in Windows for historical reasons.
|
// This one is overriden in Windows for historical reasons.
|
||||||
virtual int32 screenNameChecksum(const QString &name) const;
|
virtual int32 screenNameChecksum(const QString &name) const;
|
||||||
|
|
||||||
void setPositionInited();
|
void setPositionInited();
|
||||||
|
|
||||||
|
void createMediaView();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void savePositionByTimer() {
|
void savePositionByTimer() {
|
||||||
savePosition();
|
savePosition();
|
||||||
}
|
}
|
||||||
|
void onReActivate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updatePalette();
|
void updatePalette();
|
||||||
|
@ -95,6 +110,8 @@ private:
|
||||||
|
|
||||||
QString _titleText;
|
QString _titleText;
|
||||||
|
|
||||||
|
object_ptr<MediaView> _mediaView = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
Loading…
Reference in New Issue