Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / simple_message_box_views.cc
blobb064069c993c01468d98d95f9c831fb9238a4fc9
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/simple_message_box.h"
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/message_loop/message_pump_dispatcher.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/ui/views/constrained_window_views.h"
15 #include "grit/generated_resources.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/gfx/native_widget_types.h"
18 #include "ui/views/controls/message_box_view.h"
19 #include "ui/views/widget/widget.h"
20 #include "ui/views/window/dialog_delegate.h"
22 #if defined(USE_AURA)
23 #include "ui/aura/client/dispatcher_client.h"
24 #include "ui/aura/env.h"
25 #include "ui/aura/root_window.h"
26 #if defined(OS_WIN)
27 #include "chrome/browser/ui/views/simple_message_box_win.h"
28 #endif
29 #endif
31 namespace chrome {
33 namespace {
35 // Multiple SimpleMessageBoxViews can show up at the same time. Each of these
36 // start a nested message-loop. However, these SimpleMessageBoxViews can be
37 // deleted in any order. This creates problems if a box in an inner-loop gets
38 // destroyed before a box in an outer-loop. So to avoid this, ref-counting is
39 // used so that the SimpleMessageBoxViews gets deleted at the right time.
40 class SimpleMessageBoxViews : public views::DialogDelegate,
41 public base::MessagePumpDispatcher,
42 public base::RefCounted<SimpleMessageBoxViews> {
43 public:
44 SimpleMessageBoxViews(const base::string16& title,
45 const base::string16& message,
46 MessageBoxType type,
47 const base::string16& yes_text,
48 const base::string16& no_text);
50 MessageBoxResult result() const { return result_; }
52 // Overridden from views::DialogDelegate:
53 virtual int GetDialogButtons() const OVERRIDE;
54 virtual base::string16 GetDialogButtonLabel(
55 ui::DialogButton button) const OVERRIDE;
56 virtual bool Cancel() OVERRIDE;
57 virtual bool Accept() OVERRIDE;
59 // Overridden from views::WidgetDelegate:
60 virtual base::string16 GetWindowTitle() const OVERRIDE;
61 virtual void DeleteDelegate() OVERRIDE;
62 virtual ui::ModalType GetModalType() const OVERRIDE;
63 virtual views::View* GetContentsView() OVERRIDE;
64 virtual views::Widget* GetWidget() OVERRIDE;
65 virtual const views::Widget* GetWidget() const OVERRIDE;
67 // Overridden from MessagePumpDispatcher:
68 virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
70 private:
71 friend class base::RefCounted<SimpleMessageBoxViews>;
72 virtual ~SimpleMessageBoxViews();
74 const base::string16 window_title_;
75 const MessageBoxType type_;
76 base::string16 yes_text_;
77 base::string16 no_text_;
78 MessageBoxResult result_;
79 views::MessageBoxView* message_box_view_;
81 // Set to false as soon as the user clicks a dialog button; this tells the
82 // dispatcher we're done.
83 bool should_show_dialog_;
85 DISALLOW_COPY_AND_ASSIGN(SimpleMessageBoxViews);
88 ////////////////////////////////////////////////////////////////////////////////
89 // SimpleMessageBoxViews, public:
91 SimpleMessageBoxViews::SimpleMessageBoxViews(const base::string16& title,
92 const base::string16& message,
93 MessageBoxType type,
94 const base::string16& yes_text,
95 const base::string16& no_text)
96 : window_title_(title),
97 type_(type),
98 yes_text_(yes_text),
99 no_text_(no_text),
100 result_(MESSAGE_BOX_RESULT_NO),
101 message_box_view_(new views::MessageBoxView(
102 views::MessageBoxView::InitParams(message))),
103 should_show_dialog_(true) {
104 AddRef();
106 if (yes_text_.empty()) {
107 if (type_ == MESSAGE_BOX_TYPE_QUESTION)
108 yes_text_ =
109 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
110 else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
111 yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
112 else
113 yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
116 if (no_text_.empty()) {
117 if (type_ == MESSAGE_BOX_TYPE_QUESTION)
118 no_text_ =
119 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
120 else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
121 no_text_ = l10n_util::GetStringUTF16(IDS_CANCEL);
125 int SimpleMessageBoxViews::GetDialogButtons() const {
126 if (type_ == MESSAGE_BOX_TYPE_QUESTION ||
127 type_ == MESSAGE_BOX_TYPE_OK_CANCEL) {
128 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
131 return ui::DIALOG_BUTTON_OK;
134 base::string16 SimpleMessageBoxViews::GetDialogButtonLabel(
135 ui::DialogButton button) const {
136 if (button == ui::DIALOG_BUTTON_CANCEL)
137 return no_text_;
138 return yes_text_;
141 bool SimpleMessageBoxViews::Cancel() {
142 should_show_dialog_= false;
143 result_ = MESSAGE_BOX_RESULT_NO;
144 return true;
147 bool SimpleMessageBoxViews::Accept() {
148 should_show_dialog_ = false;
149 result_ = MESSAGE_BOX_RESULT_YES;
150 return true;
153 base::string16 SimpleMessageBoxViews::GetWindowTitle() const {
154 return window_title_;
157 void SimpleMessageBoxViews::DeleteDelegate() {
158 Release();
161 ui::ModalType SimpleMessageBoxViews::GetModalType() const {
162 return ui::MODAL_TYPE_WINDOW;
165 views::View* SimpleMessageBoxViews::GetContentsView() {
166 return message_box_view_;
169 views::Widget* SimpleMessageBoxViews::GetWidget() {
170 return message_box_view_->GetWidget();
173 const views::Widget* SimpleMessageBoxViews::GetWidget() const {
174 return message_box_view_->GetWidget();
177 bool SimpleMessageBoxViews::Dispatch(const base::NativeEvent& event) {
178 #if defined(OS_WIN)
179 TranslateMessage(&event);
180 DispatchMessage(&event);
181 #elif defined(USE_AURA)
182 aura::Env::GetInstance()->GetDispatcher()->Dispatch(event);
183 #endif
184 return should_show_dialog_;
187 ////////////////////////////////////////////////////////////////////////////////
188 // SimpleMessageBoxViews, private:
190 SimpleMessageBoxViews::~SimpleMessageBoxViews() {
193 MessageBoxResult ShowMessageBoxImpl(gfx::NativeWindow parent,
194 const base::string16& title,
195 const base::string16& message,
196 MessageBoxType type,
197 const base::string16& yes_text,
198 const base::string16& no_text) {
200 #if defined(USE_AURA) && defined(OS_WIN)
201 // If we're very early, we can't show a GPU-based dialog, so fallback to
202 // plain Windows MessageBox.
203 if (!ui::ContextFactory::GetInstance())
204 return NativeShowMessageBox(NULL, title, message, type);
205 #endif
207 scoped_refptr<SimpleMessageBoxViews> dialog(
208 new SimpleMessageBoxViews(title, message, type, yes_text, no_text));
209 CreateBrowserModalDialogViews(dialog.get(), parent)->Show();
211 #if defined(USE_AURA)
212 aura::Window* anchor = parent;
213 aura::client::DispatcherClient* client = anchor ?
214 aura::client::GetDispatcherClient(anchor->GetRootWindow()) : NULL;
215 if (!client) {
216 // Use the widget's window itself so that the message loop
217 // exists when the dialog is closed by some other means than
218 // |Cancel| or |Accept|.
219 anchor = dialog->GetWidget()->GetNativeWindow();
220 client = aura::client::GetDispatcherClient(anchor->GetRootWindow());
222 client->RunWithDispatcher(dialog.get(), anchor, true);
223 #else
225 base::MessageLoop::ScopedNestableTaskAllower allow(
226 base::MessageLoopForUI::current());
227 base::RunLoop run_loop(dialog);
228 run_loop.Run();
230 #endif
231 return dialog->result();
234 } // namespace
236 MessageBoxResult ShowMessageBox(gfx::NativeWindow parent,
237 const base::string16& title,
238 const base::string16& message,
239 MessageBoxType type) {
240 return ShowMessageBoxImpl(
241 parent, title, message, type, base::string16(), base::string16());
244 #if defined(USE_AURA)
245 MessageBoxResult ShowMessageBoxWithButtonText(gfx::NativeWindow parent,
246 const base::string16& title,
247 const base::string16& message,
248 const base::string16& yes_text,
249 const base::string16& no_text) {
250 return ShowMessageBoxImpl(
251 parent, title, message, MESSAGE_BOX_TYPE_QUESTION, yes_text, no_text);
253 #endif
255 } // namespace chrome