From 6c98350acdc0987ad6d428e9e0462fd1c16c5a8a Mon Sep 17 00:00:00 2001 From: RadRussianRus Date: Wed, 22 Apr 2020 15:15:13 +0300 Subject: [PATCH] Make text in confirm boxes selectable --- Telegram/CMakeLists.txt | 2 + .../SourceFiles/core/click_handler_types.cpp | 5 +- .../SourceFiles/history/history_widget.cpp | 3 +- .../SourceFiles/kotato/boxes/confirm_box.cpp | 215 ++++++++++++++++++ .../SourceFiles/kotato/boxes/confirm_box.h | 73 ++++++ 5 files changed, 295 insertions(+), 3 deletions(-) create mode 100644 Telegram/SourceFiles/kotato/boxes/confirm_box.cpp create mode 100644 Telegram/SourceFiles/kotato/boxes/confirm_box.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 6048332be..3b6a5a5a4 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -613,6 +613,8 @@ PRIVATE intro/intro_step.h intro/intro_widget.cpp intro/intro_widget.h + kotato/boxes/confirm_box.cpp + kotato/boxes/confirm_box.h kotato/boxes/fonts_box.cpp kotato/boxes/fonts_box.h kotato/boxes/net_boost_box.cpp diff --git a/Telegram/SourceFiles/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp index e71db35d9..cb9ffe2b8 100644 --- a/Telegram/SourceFiles/core/click_handler_types.cpp +++ b/Telegram/SourceFiles/core/click_handler_types.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwidget.h" #include "main/main_session.h" #include "boxes/confirm_box.h" +#include "kotato/boxes/confirm_box.h" #include "base/qthelp_regex.h" #include "storage/localstorage.h" #include "history/view/history_view_element.h" @@ -60,10 +61,10 @@ void HiddenUrlClickHandler::Open(QString url, QVariant context) { ? QString::fromUtf8(parsedUrl.toEncoded()) : ShowEncoded(displayed); Ui::show( - Box( + Box( (tr::lng_open_this_link(tr::now) + qsl("\n\n") - + displayUrl), + + textcmdLink(displayUrl, displayUrl)), tr::lng_open_link(tr::now), [=] { Ui::hideLayer(); open(); }), Ui::LayerOption::KeepOther); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 2030e966e..31139a1f6 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/send_files_box.h" #include "boxes/share_box.h" #include "boxes/edit_caption_box.h" +#include "kotato/boxes/confirm_box.h" #include "kotato/boxes/unpin_box.h" #include "core/file_utilities.h" #include "ui/toast/toast.h" @@ -3709,7 +3710,7 @@ void HistoryWidget::botCallbackDone( answer.match([&](const MTPDmessages_botCallbackAnswer &data) { if (const auto message = data.vmessage()) { if (data.is_alert()) { - Ui::show(Box(qs(*message))); + Ui::show(Box(qs(*message))); } else { Ui::Toast::Show(qs(*message)); } diff --git a/Telegram/SourceFiles/kotato/boxes/confirm_box.cpp b/Telegram/SourceFiles/kotato/boxes/confirm_box.cpp new file mode 100644 index 000000000..c7d7cdda2 --- /dev/null +++ b/Telegram/SourceFiles/kotato/boxes/confirm_box.cpp @@ -0,0 +1,215 @@ +/* +This file is part of Kotatogram Desktop, +the unofficial app based on Telegram Desktop. + +For license and copyright information please follow this link: +https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL +*/ +#include "kotato/boxes/confirm_box.h" + +#include "lang/lang_keys.h" +#include "ui/widgets/labels.h" +#include "styles/style_layers.h" +#include "styles/style_boxes.h" + +namespace Kotato { + +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + FnMut confirmedCallback, + FnMut cancelledCallback) +: _confirmText(tr::lng_box_ok(tr::now)) +, _cancelText(tr::lng_cancel(tr::now)) +, _confirmStyle(st::defaultBoxButton) +, _text(this, st::boxLabel) +, _confirmedCallback(std::move(confirmedCallback)) +, _cancelledCallback(std::move(cancelledCallback)) { + init(text); +} + +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + const QString &confirmText, + FnMut confirmedCallback, + FnMut cancelledCallback) +: _confirmText(confirmText) +, _cancelText(tr::lng_cancel(tr::now)) +, _confirmStyle(st::defaultBoxButton) +, _text(this, st::boxLabel) +, _confirmedCallback(std::move(confirmedCallback)) +, _cancelledCallback(std::move(cancelledCallback)) { + init(text); +} + +ConfirmBox::ConfirmBox( + QWidget*, + const TextWithEntities &text, + const QString &confirmText, + FnMut confirmedCallback, + FnMut cancelledCallback) +: _confirmText(confirmText) +, _cancelText(tr::lng_cancel(tr::now)) +, _confirmStyle(st::defaultBoxButton) +, _text(this, st::boxLabel) +, _confirmedCallback(std::move(confirmedCallback)) +, _cancelledCallback(std::move(cancelledCallback)) { + init(text); +} + +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + const QString &confirmText, + const style::RoundButton &confirmStyle, + FnMut confirmedCallback, + FnMut cancelledCallback) +: _confirmText(confirmText) +, _cancelText(tr::lng_cancel(tr::now)) +, _confirmStyle(confirmStyle) +, _text(this, st::boxLabel) +, _confirmedCallback(std::move(confirmedCallback)) +, _cancelledCallback(std::move(cancelledCallback)) { + init(text); +} + +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + const QString &confirmText, + const QString &cancelText, + FnMut confirmedCallback, + FnMut cancelledCallback) +: _confirmText(confirmText) +, _cancelText(cancelText) +, _confirmStyle(st::defaultBoxButton) +, _text(this, st::boxLabel) +, _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, + FnMut confirmedCallback, + FnMut cancelledCallback) +: _confirmText(confirmText) +, _cancelText(cancelText) +, _confirmStyle(st::defaultBoxButton) +, _text(this, st::boxLabel) +, _confirmedCallback(std::move(confirmedCallback)) +, _cancelledCallback(std::move(cancelledCallback)) { + init(text); +} + +ConfirmBox::ConfirmBox( + const InformBoxTag &, + const QString &text, + const QString &doneText, + Fn closedCallback) +: _confirmText(doneText) +, _confirmStyle(st::defaultBoxButton) +, _informative(true) +, _text(this, st::boxLabel) +, _confirmedCallback(generateInformCallback(closedCallback)) +, _cancelledCallback(generateInformCallback(closedCallback)) { + init(text); +} + +ConfirmBox::ConfirmBox( + const InformBoxTag &, + const TextWithEntities &text, + const QString &doneText, + Fn closedCallback) +: _confirmText(doneText) +, _confirmStyle(st::defaultBoxButton) +, _informative(true) +, _text(this, st::boxLabel) +, _confirmedCallback(generateInformCallback(closedCallback)) +, _cancelledCallback(generateInformCallback(closedCallback)) { + init(text); +} + +FnMut ConfirmBox::generateInformCallback( + Fn closedCallback) { + return crl::guard(this, [=] { + closeBox(); + if (closedCallback) { + closedCallback(); + } + }); +} + +void ConfirmBox::init(const QString &text) { + _text->setRichText(text); +} + +void ConfirmBox::init(const TextWithEntities &text) { + _text->setMarkedText(text); +} + +void ConfirmBox::prepare() { + addButton( + rpl::single(_confirmText), + [=] { confirmed(); }, + _confirmStyle); + if (!_informative) { + addButton( + rpl::single(_cancelText), + [=] { _cancelled = true; closeBox(); }); + } + + boxClosing() | rpl::start_with_next([=] { + if (!_confirmed && (!_strictCancel || _cancelled)) { + if (auto callback = std::move(_cancelledCallback)) { + callback(); + } + } + }, lifetime()); + + _text->setSelectable(true); + _text->setLinksTrusted(); + + setDimensions(st::boxWidth, st::boxPadding.top() + _text->height() + st::boxPadding.bottom()); +} + +void ConfirmBox::resizeEvent(QResizeEvent *e) { + BoxContent::resizeEvent(e); + _text->moveToLeft(st::boxPadding.left(), st::boxPadding.top()); +} + +void ConfirmBox::confirmed() { + if (!_confirmed) { + _confirmed = true; + if (auto callback = std::move(_confirmedCallback)) { + callback(); + } + } +} + +void ConfirmBox::keyPressEvent(QKeyEvent *e) { + if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { + confirmed(); + } else { + BoxContent::keyPressEvent(e); + } +} + +InformBox::InformBox(QWidget*, const QString &text, Fn closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, tr::lng_box_ok(tr::now), std::move(closedCallback)) { +} + +InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, Fn closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std::move(closedCallback)) { +} + +InformBox::InformBox(QWidget*, const TextWithEntities &text, Fn closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, tr::lng_box_ok(tr::now), std::move(closedCallback)) { +} + +InformBox::InformBox(QWidget*, const TextWithEntities &text, const QString &doneText, Fn closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, doneText, std::move(closedCallback)) { +} + +} // namespace Kotato \ No newline at end of file diff --git a/Telegram/SourceFiles/kotato/boxes/confirm_box.h b/Telegram/SourceFiles/kotato/boxes/confirm_box.h new file mode 100644 index 000000000..f1004b4aa --- /dev/null +++ b/Telegram/SourceFiles/kotato/boxes/confirm_box.h @@ -0,0 +1,73 @@ +/* +This file is part of Kotatogram Desktop, +the unofficial app based on Telegram Desktop. + +For license and copyright information please follow this link: +https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL +*/ +#pragma once + +#include "boxes/abstract_box.h" + +namespace Ui { +class FlatLabel; +} // namespace Ui + +namespace Kotato { +class InformBox; +class ConfirmBox : public Ui::BoxContent { +public: + ConfirmBox(QWidget*, const QString &text, FnMut confirmedCallback = FnMut(), FnMut cancelledCallback = FnMut()); + ConfirmBox(QWidget*, const QString &text, const QString &confirmText, FnMut confirmedCallback = FnMut(), FnMut cancelledCallback = FnMut()); + ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, FnMut confirmedCallback = FnMut(), FnMut cancelledCallback = FnMut()); + ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const QString &cancelText, FnMut confirmedCallback = FnMut(), FnMut cancelledCallback = FnMut()); + ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, const QString &cancelText, FnMut confirmedCallback = FnMut(), FnMut cancelledCallback = FnMut()); + ConfirmBox(QWidget*, const TextWithEntities &text, const QString &confirmText, FnMut confirmedCallback = nullptr, FnMut cancelledCallback = nullptr); + + // If strict cancel is set the cancelledCallback is only called if the cancel button was pressed. + void setStrictCancel(bool strictCancel) { + _strictCancel = strictCancel; + } + +protected: + void prepare() override; + + void resizeEvent(QResizeEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + +private: + struct InformBoxTag { + }; + ConfirmBox(const InformBoxTag &, const QString &text, const QString &doneText, Fn closedCallback); + ConfirmBox(const InformBoxTag &, const TextWithEntities &text, const QString &doneText, Fn closedCallback); + FnMut generateInformCallback(Fn closedCallback); + friend class InformBox; + + void confirmed(); + void init(const QString &text); + void init(const TextWithEntities &text); + + QString _confirmText; + QString _cancelText; + const style::RoundButton &_confirmStyle; + bool _informative = false; + + object_ptr _text; + + bool _confirmed = false; + bool _cancelled = false; + bool _strictCancel = false; + FnMut _confirmedCallback; + FnMut _cancelledCallback; + +}; + +class InformBox : public ConfirmBox { +public: + InformBox(QWidget*, const QString &text, Fn closedCallback = nullptr); + InformBox(QWidget*, const QString &text, const QString &doneText, Fn closedCallback = nullptr); + InformBox(QWidget*, const TextWithEntities &text, Fn closedCallback = nullptr); + InformBox(QWidget*, const TextWithEntities &text, const QString &doneText, Fn closedCallback = nullptr); + +}; +} // namespace Kotato \ No newline at end of file