blob: 8a7eadca6179326db8b7535569c248bb598835e2 [file] [log] [blame]
Avi Drissmand6cdf9b2022-09-15 19:52:531// Copyright 2016 The Chromium Authors
joedow7cc2c862016-09-13 16:05:572// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
joedow6243fba2016-09-14 18:13:495#include <gtk/gtk.h>
6
7#include <memory>
8#include <string>
Daniel Chengce48c3c42019-04-26 15:06:089#include <utility>
joedow6243fba2016-09-14 18:13:4910
Avi Drissman135261e2023-01-11 22:43:1511#include "base/functional/bind.h"
12#include "base/functional/callback.h"
joedow6243fba2016-09-14 18:13:4913#include "base/i18n/message_formatter.h"
14#include "base/location.h"
15#include "base/logging.h"
joedow6243fba2016-09-14 18:13:4916#include "base/strings/utf_string_conversions.h"
17#include "base/time/time.h"
18#include "base/timer/timer.h"
19#include "remoting/base/string_resources.h"
joedow7cc2c862016-09-13 16:05:5720#include "remoting/host/it2me/it2me_confirmation_dialog.h"
joedow6243fba2016-09-14 18:13:4921#include "ui/base/glib/glib_signal.h"
22#include "ui/base/l10n/l10n_util.h"
joedow7cc2c862016-09-13 16:05:5723
24namespace remoting {
25
joedow6243fba2016-09-14 18:13:4926namespace {
27
28// Time to wait before closing the dialog and cancelling the connection.
Peter Kastinge5a38ed2021-10-02 03:06:3529constexpr base::TimeDelta kDialogTimeout = base::Minutes(1);
joedow6243fba2016-09-14 18:13:4930
31class It2MeConfirmationDialogLinux : public It2MeConfirmationDialog {
32 public:
33 It2MeConfirmationDialogLinux();
Peter Boströme9178e42021-09-22 18:11:4934
35 It2MeConfirmationDialogLinux(const It2MeConfirmationDialogLinux&) = delete;
36 It2MeConfirmationDialogLinux& operator=(const It2MeConfirmationDialogLinux&) =
37 delete;
38
joedow6243fba2016-09-14 18:13:4939 ~It2MeConfirmationDialogLinux() override;
40
41 // It2MeConfirmationDialog implementation.
42 void Show(const std::string& remote_user_email,
Evan Stade835674b2020-06-16 17:20:0443 ResultCallback callback) override;
joedow6243fba2016-09-14 18:13:4944
45 private:
46 // Creates a dialog window and makes it visible.
47 void CreateWindow(const std::string& remote_user_email);
48
49 // Destroys the dialog window (if created) and stop |dialog_timer_|.
50 void Hide();
51
52 // Handles user input from the dialog.
53 CHROMEG_CALLBACK_1(It2MeConfirmationDialogLinux, void, OnResponse, GtkDialog*,
54 int);
55
56 GtkWidget* confirmation_window_ = nullptr;
57
58 ResultCallback result_callback_;
59
60 base::OneShotTimer dialog_timer_;
joedow6243fba2016-09-14 18:13:4961};
62
63It2MeConfirmationDialogLinux::It2MeConfirmationDialogLinux() {}
64
65It2MeConfirmationDialogLinux::~It2MeConfirmationDialogLinux() {
66 Hide();
67}
68
69void It2MeConfirmationDialogLinux::Show(const std::string& remote_user_email,
Evan Stade835674b2020-06-16 17:20:0470 ResultCallback callback) {
joedow6243fba2016-09-14 18:13:4971 DCHECK(!remote_user_email.empty());
72 DCHECK(callback);
73 DCHECK(!result_callback_);
74
Evan Stade835674b2020-06-16 17:20:0475 result_callback_ = std::move(callback);
joedow6243fba2016-09-14 18:13:4976
77 CreateWindow(remote_user_email);
78
79 dialog_timer_.Start(FROM_HERE, kDialogTimeout,
Jan Wilken Dörriea0e772a2020-04-01 18:28:1980 base::BindOnce(&It2MeConfirmationDialogLinux::OnResponse,
81 base::Unretained(this),
82 /*dialog=*/nullptr, GTK_RESPONSE_NONE));
joedow6243fba2016-09-14 18:13:4983}
84
85void It2MeConfirmationDialogLinux::Hide() {
86 dialog_timer_.Stop();
87
88 if (confirmation_window_) {
89 gtk_widget_destroy(confirmation_window_);
90 confirmation_window_ = nullptr;
91 }
92}
93
94void It2MeConfirmationDialogLinux::CreateWindow(
95 const std::string& remote_user_email) {
96 DCHECK(!confirmation_window_);
97
98 confirmation_window_ = gtk_dialog_new_with_buttons(
99 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME).c_str(),
100 /*parent=*/nullptr,
101 static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL),
102 l10n_util::GetStringUTF8(IDS_SHARE_CONFIRM_DIALOG_DECLINE).c_str(),
103 GTK_RESPONSE_CANCEL,
104 l10n_util::GetStringUTF8(IDS_SHARE_CONFIRM_DIALOG_CONFIRM).c_str(),
105 GTK_RESPONSE_OK,
106 /*next_button=*/nullptr);
107
108 gtk_dialog_set_default_response(GTK_DIALOG(confirmation_window_),
109 GTK_RESPONSE_CANCEL);
110
111 gtk_window_set_resizable(GTK_WINDOW(confirmation_window_), false);
112
113 gtk_window_set_keep_above(GTK_WINDOW(confirmation_window_), true);
114
115 g_signal_connect(confirmation_window_, "response",
116 G_CALLBACK(OnResponseThunk), this);
117
118 GtkWidget* content_area =
119 gtk_dialog_get_content_area(GTK_DIALOG(confirmation_window_));
120
Jan Wilken Dörrie739ccc212021-03-11 18:13:05121 std::u16string dialog_text =
joedow6243fba2016-09-14 18:13:49122 base::i18n::MessageFormatter::FormatWithNumberedArgs(
123 l10n_util::GetStringUTF16(
124 IDS_SHARE_CONFIRM_DIALOG_MESSAGE_WITH_USERNAME),
125 remote_user_email);
126 GtkWidget* text_label = gtk_label_new(base::UTF16ToUTF8(dialog_text).c_str());
127 gtk_label_set_line_wrap(GTK_LABEL(text_label), true);
Tom Andersonafb06602018-08-23 23:13:09128#if GTK_CHECK_VERSION(3, 90, 0)
129 gtk_widget_set_margin_start(GTK_WIDGET(text_label), 12);
130 gtk_widget_set_margin_end(GTK_WIDGET(text_label), 12);
131 gtk_widget_set_margin_top(GTK_WIDGET(text_label), 12);
132 gtk_widget_set_margin_bottom(GTK_WIDGET(text_label), 12);
133#else
thomasandersonac0b0fc2017-03-11 03:15:04134 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
joedow6243fba2016-09-14 18:13:49135 gtk_misc_set_padding(GTK_MISC(text_label), 12, 12);
thomasandersonac0b0fc2017-03-11 03:15:04136 G_GNUC_END_IGNORE_DEPRECATIONS;
Tom Andersonafb06602018-08-23 23:13:09137#endif
joedow6243fba2016-09-14 18:13:49138
139 gtk_container_add(GTK_CONTAINER(content_area), text_label);
Tom Andersonafb06602018-08-23 23:13:09140#if !GTK_CHECK_VERSION(3, 90, 0)
joedow6243fba2016-09-14 18:13:49141 gtk_widget_show_all(content_area);
Tom Andersonafb06602018-08-23 23:13:09142#endif
joedow6243fba2016-09-14 18:13:49143
144 gtk_window_set_urgency_hint(GTK_WINDOW(confirmation_window_), true);
145 gtk_window_present(GTK_WINDOW(confirmation_window_));
146}
147
148void It2MeConfirmationDialogLinux::OnResponse(GtkDialog* dialog,
149 int response_id) {
150 DCHECK(result_callback_);
151
152 Hide();
Daniel Chengce48c3c42019-04-26 15:06:08153 std::move(result_callback_)
154 .Run((response_id == GTK_RESPONSE_OK) ? Result::OK : Result::CANCEL);
joedow6243fba2016-09-14 18:13:49155}
156
157} // namespace
158
joedowd15dc6a2017-03-20 16:52:26159std::unique_ptr<It2MeConfirmationDialog>
160It2MeConfirmationDialogFactory::Create() {
Jinho Bang138fde32018-01-18 23:13:42161 return std::make_unique<It2MeConfirmationDialogLinux>();
joedow7cc2c862016-09-13 16:05:57162}
163
164} // namespace remoting