tdesktop/Telegram/SourceFiles/ui/boxes/confirm_box.cpp

448 lines
10 KiB
C++
Raw Normal View History

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
2021-10-18 21:36:55 +00:00
#include "ui/boxes/confirm_box.h"
2017-04-13 08:27:10 +00:00
#include "lang/lang_keys.h"
#include "ui/widgets/checkbox.h"
2018-12-05 08:07:17 +00:00
#include "ui/wrap/vertical_layout.h"
2019-09-18 11:19:05 +00:00
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
2021-10-18 22:28:08 +00:00
namespace Ui {
namespace {
TextParseOptions kInformBoxTextOptions = {
(TextParseLinks
| TextParseMultiline
2022-01-07 03:50:06 +00:00
| TextParseMarkdown), // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions kMarkedTextBoxOptions = {
(TextParseLinks
| TextParseMultiline
| TextParseMarkdown
| TextParseMentions
| TextParseHashtags), // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
} // namespace
ConfirmBox::ConfirmBox(
QWidget*,
const QString &text,
ConfirmBox::ConfirmedCallback confirmedCallback,
FnMut<void()> cancelledCallback)
2019-06-19 15:09:03 +00:00
: _confirmText(tr::lng_box_ok(tr::now))
, _cancelText(tr::lng_cancel(tr::now))
, _confirmStyle(st::defaultBoxButton)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(std::move(confirmedCallback))
, _cancelledCallback(std::move(cancelledCallback)) {
init(text);
}
ConfirmBox::ConfirmBox(
QWidget*,
const QString &text,
const QString &confirmText,
ConfirmBox::ConfirmedCallback confirmedCallback,
FnMut<void()> cancelledCallback)
: _confirmText(confirmText)
2019-06-19 15:09:03 +00:00
, _cancelText(tr::lng_cancel(tr::now))
, _confirmStyle(st::defaultBoxButton)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(std::move(confirmedCallback))
, _cancelledCallback(std::move(cancelledCallback)) {
init(text);
}
ConfirmBox::ConfirmBox(
QWidget*,
const TextWithEntities &text,
const QString &confirmText,
ConfirmBox::ConfirmedCallback confirmedCallback,
FnMut<void()> cancelledCallback)
: _confirmText(confirmText)
2019-06-19 15:09:03 +00:00
, _cancelText(tr::lng_cancel(tr::now))
, _confirmStyle(st::defaultBoxButton)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(std::move(confirmedCallback))
, _cancelledCallback(std::move(cancelledCallback)) {
init(text);
}
ConfirmBox::ConfirmBox(
QWidget*,
const QString &text,
const QString &confirmText,
const style::RoundButton &confirmStyle,
ConfirmBox::ConfirmedCallback confirmedCallback,
FnMut<void()> cancelledCallback)
: _confirmText(confirmText)
2019-06-19 15:09:03 +00:00
, _cancelText(tr::lng_cancel(tr::now))
, _confirmStyle(confirmStyle)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(std::move(confirmedCallback))
, _cancelledCallback(std::move(cancelledCallback)) {
init(text);
}
ConfirmBox::ConfirmBox(
QWidget*,
const QString &text,
const QString &confirmText,
const QString &cancelText,
ConfirmBox::ConfirmedCallback confirmedCallback,
FnMut<void()> cancelledCallback)
: _confirmText(confirmText)
, _cancelText(cancelText)
, _confirmStyle(st::defaultBoxButton)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(std::move(confirmedCallback))
, _cancelledCallback(std::move(cancelledCallback)) {
init(text);
}
ConfirmBox::ConfirmBox(
QWidget*,
const QString &text,
const QString &confirmText,
const style::RoundButton &confirmStyle,
const QString &cancelText,
ConfirmBox::ConfirmedCallback confirmedCallback,
FnMut<void()> cancelledCallback)
: _confirmText(confirmText)
, _cancelText(cancelText)
, _confirmStyle(st::defaultBoxButton)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(std::move(confirmedCallback))
, _cancelledCallback(std::move(cancelledCallback)) {
init(text);
}
ConfirmBox::ConfirmBox(
const InformBoxTag &,
const QString &text,
const QString &doneText,
Fn<void()> closedCallback)
: _confirmText(doneText)
, _confirmStyle(st::defaultBoxButton)
2016-03-04 22:04:15 +00:00
, _informative(true)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(generateInformCallback(closedCallback))
, _cancelledCallback(generateInformCallback(closedCallback)) {
init(text);
}
ConfirmBox::ConfirmBox(
const InformBoxTag &,
const TextWithEntities &text,
const QString &doneText,
Fn<void()> closedCallback)
: _confirmText(doneText)
, _confirmStyle(st::defaultBoxButton)
, _informative(true)
2021-10-18 21:36:55 +00:00
, _text(st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right())
, _confirmedCallback(generateInformCallback(closedCallback))
, _cancelledCallback(generateInformCallback(closedCallback)) {
init(text);
}
FnMut<void()> ConfirmBox::generateInformCallback(
Fn<void()> closedCallback) {
return crl::guard(this, [=] {
closeBox();
if (closedCallback) {
closedCallback();
}
});
}
void ConfirmBox::init(const QString &text) {
_text.setText(
st::boxLabelStyle,
text,
_informative ? kInformBoxTextOptions : kPlainTextOptions);
}
void ConfirmBox::init(const TextWithEntities &text) {
_text.setMarkedText(st::boxLabelStyle, text, kMarkedTextBoxOptions);
}
void ConfirmBox::prepare() {
addButton(
rpl::single(_confirmText),
[=] { confirmed(); },
_confirmStyle);
if (!_informative) {
addButton(
rpl::single(_cancelText),
[=] { _cancelled = true; closeBox(); });
}
boxClosing() | rpl::start_with_next([=] {
2018-11-26 11:00:31 +00:00
if (!_confirmed && (!_strictCancel || _cancelled)) {
if (auto callback = std::move(_cancelledCallback)) {
callback();
}
}
}, lifetime());
textUpdated();
}
2018-05-30 15:08:12 +00:00
void ConfirmBox::setMaxLineCount(int count) {
if (_maxLineCount != count) {
_maxLineCount = count;
textUpdated();
}
}
void ConfirmBox::textUpdated() {
2021-10-18 21:36:55 +00:00
_textWidth = st::boxWidth
- st::boxPadding.left()
- st::defaultBox.buttonPadding.right();
2018-05-30 15:08:12 +00:00
_textHeight = _text.countHeight(_textWidth);
if (_maxLineCount > 0) {
2021-10-18 21:36:55 +00:00
accumulate_min(
_textHeight,
_maxLineCount * st::boxLabelStyle.lineHeight);
2018-05-30 15:08:12 +00:00
}
2021-10-18 21:36:55 +00:00
setDimensions(
st::boxWidth,
st::boxPadding.top() + _textHeight + st::boxPadding.bottom());
setMouseTracking(_text.hasLinks());
}
void ConfirmBox::confirmed() {
if (!_confirmed) {
_confirmed = true;
const auto confirmed = &_confirmedCallback;
if (const auto callbackPtr = std::get_if<1>(confirmed)) {
if (auto callback = base::take(*callbackPtr)) {
callback();
}
} else if (const auto callbackPtr = std::get_if<2>(confirmed)) {
if (auto callback = base::take(*callbackPtr)) {
const auto weak = Ui::MakeWeak(this);
callback(crl::guard(weak, [=] { closeBox(); }));
}
}
}
}
void ConfirmBox::mouseMoveEvent(QMouseEvent *e) {
_lastMousePos = e->globalPos();
updateHover();
}
void ConfirmBox::mousePressEvent(QMouseEvent *e) {
_lastMousePos = e->globalPos();
updateHover();
ClickHandler::pressed();
return BoxContent::mousePressEvent(e);
}
void ConfirmBox::mouseReleaseEvent(QMouseEvent *e) {
_lastMousePos = e->globalPos();
updateHover();
2018-11-26 11:00:31 +00:00
if (const auto activated = ClickHandler::unpressed()) {
ActivateClickHandler(window(), activated, e->button());
crl::on_main(this, [=] {
closeBox();
});
2018-11-26 11:00:31 +00:00
return;
}
2018-11-26 11:00:31 +00:00
BoxContent::mouseReleaseEvent(e);
}
void ConfirmBox::leaveEventHook(QEvent *e) {
ClickHandler::clearActive(this);
}
2021-10-18 21:36:55 +00:00
void ConfirmBox::clickHandlerActiveChanged(
const ClickHandlerPtr &p,
bool active) {
setCursor(active ? style::cur_pointer : style::cur_default);
update();
}
2021-10-18 21:36:55 +00:00
void ConfirmBox::clickHandlerPressedChanged(
const ClickHandlerPtr &p,
bool pressed) {
update();
}
void ConfirmBox::updateLink() {
_lastMousePos = QCursor::pos();
updateHover();
}
void ConfirmBox::updateHover() {
2021-10-18 21:36:55 +00:00
const auto m = mapFromGlobal(_lastMousePos);
const auto state = _text.getStateLeft(
m - QPoint(st::boxPadding.left(), st::boxPadding.top()),
_textWidth,
width());
ClickHandler::setActive(state.link, this);
}
void ConfirmBox::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
confirmed();
} else {
BoxContent::keyPressEvent(e);
}
}
void ConfirmBox::paintEvent(QPaintEvent *e) {
BoxContent::paintEvent(e);
Painter p(this);
// draw box title / text
2016-10-31 12:29:26 +00:00
p.setPen(st::boxTextFg);
2018-05-30 15:08:12 +00:00
if (_maxLineCount > 0) {
2021-10-18 21:36:55 +00:00
_text.drawLeftElided(
p,
st::boxPadding.left(),
st::boxPadding.top(),
_textWidth,
width(),
_maxLineCount,
style::al_left);
2018-05-30 15:08:12 +00:00
} else {
2021-10-18 21:36:55 +00:00
_text.drawLeft(
p,
st::boxPadding.left(),
st::boxPadding.top(),
_textWidth,
width(),
style::al_left);
2018-05-30 15:08:12 +00:00
}
}
2021-10-18 21:36:55 +00:00
InformBox::InformBox(
QWidget*,
const QString &text, Fn<void()> closedCallback)
: ConfirmBox(
ConfirmBox::InformBoxTag(),
text,
tr::lng_box_ok(tr::now),
std::move(closedCallback)) {
}
2021-10-18 21:36:55 +00:00
InformBox::InformBox(
QWidget*,
const QString &text,
const QString &doneText,
Fn<void()> closedCallback)
: ConfirmBox(
ConfirmBox::InformBoxTag(),
text,
doneText,
std::move(closedCallback)) {
}
2021-10-18 21:36:55 +00:00
InformBox::InformBox(
QWidget*,
const TextWithEntities &text,
Fn<void()> closedCallback)
: ConfirmBox(
ConfirmBox::InformBoxTag(),
text,
tr::lng_box_ok(tr::now),
std::move(closedCallback)) {
}
2021-10-18 21:36:55 +00:00
InformBox::InformBox(
QWidget*,
const TextWithEntities &text,
const QString &doneText,
Fn<void()> closedCallback)
: ConfirmBox(
ConfirmBox::InformBoxTag(),
text,
doneText,
std::move(closedCallback)) {
}
2018-12-05 08:07:17 +00:00
ConfirmDontWarnBox::ConfirmDontWarnBox(
QWidget*,
rpl::producer<TextWithEntities> text,
2018-12-05 08:07:17 +00:00
const QString &checkbox,
rpl::producer<QString> confirm,
2018-12-05 08:07:17 +00:00
FnMut<void(bool)> callback)
: _confirm(std::move(confirm))
, _content(setupContent(std::move(text), checkbox, std::move(callback))) {
2018-12-05 08:07:17 +00:00
}
void ConfirmDontWarnBox::prepare() {
setDimensionsToContent(st::boxWidth, _content);
addButton(std::move(_confirm), [=] { _callback(); });
addButton(tr::lng_cancel(), [=] { closeBox(); });
2018-12-05 08:07:17 +00:00
}
not_null<Ui::RpWidget*> ConfirmDontWarnBox::setupContent(
rpl::producer<TextWithEntities> text,
2018-12-05 08:07:17 +00:00
const QString &checkbox,
FnMut<void(bool)> callback) {
const auto result = Ui::CreateChild<Ui::VerticalLayout>(this);
result->add(
object_ptr<Ui::FlatLabel>(
result,
std::move(text),
2018-12-05 08:07:17 +00:00
st::boxLabel),
st::boxPadding);
const auto control = result->add(
object_ptr<Ui::Checkbox>(
result,
checkbox,
false,
st::defaultBoxCheckbox),
style::margins(
st::boxPadding.left(),
st::boxPadding.bottom(),
st::boxPadding.right(),
st::boxPadding.bottom()));
_callback = [=, callback = std::move(callback)]() mutable {
const auto checked = control->checked();
auto local = std::move(callback);
closeBox();
local(checked);
};
return result;
}
2021-10-18 22:28:08 +00:00
} // namespace Ui