NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / ui / views / simple_message_box_views.cc
blob3e85e682801ae7e81d72f5bfd0c917303d82f1f7
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/aura/client/dispatcher_client.h"
17 #include "ui/aura/env.h"
18 #include "ui/aura/root_window.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/gfx/native_widget_types.h"
21 #include "ui/views/controls/message_box_view.h"
22 #include "ui/views/widget/widget.h"
23 #include "ui/views/window/dialog_delegate.h"
25 #if defined(OS_WIN)
26 #include "chrome/browser/ui/views/simple_message_box_win.h"
27 #endif
29 namespace chrome {
31 namespace {
33 // Multiple SimpleMessageBoxViews can show up at the same time. Each of these
34 // start a nested message-loop. However, these SimpleMessageBoxViews can be
35 // deleted in any order. This creates problems if a box in an inner-loop gets
36 // destroyed before a box in an outer-loop. So to avoid this, ref-counting is
37 // used so that the SimpleMessageBoxViews gets deleted at the right time.
38 class SimpleMessageBoxViews : public views::DialogDelegate,
39 public base::MessagePumpDispatcher,
40 public base::RefCounted<SimpleMessageBoxViews> {
41 public:
42 SimpleMessageBoxViews(const base::string16& title,
43 const base::string16& message,
44 MessageBoxType type,
45 const base::string16& yes_text,
46 const base::string16& no_text);
48 MessageBoxResult result() const { return result_; }
50 // Overridden from views::DialogDelegate:
51 virtual int GetDialogButtons() const OVERRIDE;
52 virtual base::string16 GetDialogButtonLabel(
53 ui::DialogButton button) const OVERRIDE;
54 virtual bool Cancel() OVERRIDE;
55 virtual bool Accept() OVERRIDE;
57 // Overridden from views::WidgetDelegate:
58 virtual base::string16 GetWindowTitle() const OVERRIDE;
59 virtual void DeleteDelegate() OVERRIDE;
60 virtual ui::ModalType GetModalType() const OVERRIDE;
61 virtual views::View* GetContentsView() OVERRIDE;
62 virtual views::Widget* GetWidget() OVERRIDE;
63 virtual const views::Widget* GetWidget() const OVERRIDE;
65 // Overridden from MessagePumpDispatcher:
66 virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE;
68 private:
69 friend class base::RefCounted<SimpleMessageBoxViews>;
70 virtual ~SimpleMessageBoxViews();
72 const base::string16 window_title_;
73 const MessageBoxType type_;
74 base::string16 yes_text_;
75 base::string16 no_text_;
76 MessageBoxResult result_;
77 views::MessageBoxView* message_box_view_;
79 // Set to false as soon as the user clicks a dialog button; this tells the
80 // dispatcher we're done.
81 bool should_show_dialog_;
83 DISALLOW_COPY_AND_ASSIGN(SimpleMessageBoxViews);
86 ////////////////////////////////////////////////////////////////////////////////
87 // SimpleMessageBoxViews, public:
89 SimpleMessageBoxViews::SimpleMessageBoxViews(const base::string16& title,
90 const base::string16& message,
91 MessageBoxType type,
92 const base::string16& yes_text,
93 const base::string16& no_text)
94 : window_title_(title),
95 type_(type),
96 yes_text_(yes_text),
97 no_text_(no_text),
98 result_(MESSAGE_BOX_RESULT_NO),
99 message_box_view_(new views::MessageBoxView(
100 views::MessageBoxView::InitParams(message))),
101 should_show_dialog_(true) {
102 AddRef();
104 if (yes_text_.empty()) {
105 if (type_ == MESSAGE_BOX_TYPE_QUESTION)
106 yes_text_ =
107 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
108 else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
109 yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
110 else
111 yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
114 if (no_text_.empty()) {
115 if (type_ == MESSAGE_BOX_TYPE_QUESTION)
116 no_text_ =
117 l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
118 else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
119 no_text_ = l10n_util::GetStringUTF16(IDS_CANCEL);
123 int SimpleMessageBoxViews::GetDialogButtons() const {
124 if (type_ == MESSAGE_BOX_TYPE_QUESTION ||
125 type_ == MESSAGE_BOX_TYPE_OK_CANCEL) {
126 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
129 return ui::DIALOG_BUTTON_OK;
132 base::string16 SimpleMessageBoxViews::GetDialogButtonLabel(
133 ui::DialogButton button) const {
134 if (button == ui::DIALOG_BUTTON_CANCEL)
135 return no_text_;
136 return yes_text_;
139 bool SimpleMessageBoxViews::Cancel() {
140 should_show_dialog_= false;
141 result_ = MESSAGE_BOX_RESULT_NO;
142 return true;
145 bool SimpleMessageBoxViews::Accept() {
146 should_show_dialog_ = false;
147 result_ = MESSAGE_BOX_RESULT_YES;
148 return true;
151 base::string16 SimpleMessageBoxViews::GetWindowTitle() const {
152 return window_title_;
155 void SimpleMessageBoxViews::DeleteDelegate() {
156 Release();
159 ui::ModalType SimpleMessageBoxViews::GetModalType() const {
160 return ui::MODAL_TYPE_WINDOW;
163 views::View* SimpleMessageBoxViews::GetContentsView() {
164 return message_box_view_;
167 views::Widget* SimpleMessageBoxViews::GetWidget() {
168 return message_box_view_->GetWidget();
171 const views::Widget* SimpleMessageBoxViews::GetWidget() const {
172 return message_box_view_->GetWidget();
175 uint32_t SimpleMessageBoxViews::Dispatch(const base::NativeEvent& event) {
176 uint32_t action = POST_DISPATCH_PERFORM_DEFAULT;
177 if (!should_show_dialog_)
178 action |= POST_DISPATCH_QUIT_LOOP;
179 return action;
182 ////////////////////////////////////////////////////////////////////////////////
183 // SimpleMessageBoxViews, private:
185 SimpleMessageBoxViews::~SimpleMessageBoxViews() {
188 MessageBoxResult ShowMessageBoxImpl(gfx::NativeWindow parent,
189 const base::string16& title,
190 const base::string16& message,
191 MessageBoxType type,
192 const base::string16& yes_text,
193 const base::string16& no_text) {
195 #if defined(OS_WIN)
196 // If we're very early, we can't show a GPU-based dialog, so fallback to
197 // plain Windows MessageBox.
198 if (!ui::ContextFactory::GetInstance())
199 return NativeShowMessageBox(NULL, title, message, type);
200 #endif
202 scoped_refptr<SimpleMessageBoxViews> dialog(
203 new SimpleMessageBoxViews(title, message, type, yes_text, no_text));
204 CreateBrowserModalDialogViews(dialog.get(), parent)->Show();
206 aura::Window* anchor = parent;
207 aura::client::DispatcherClient* client = anchor ?
208 aura::client::GetDispatcherClient(anchor->GetRootWindow()) : NULL;
209 if (!client) {
210 // Use the widget's window itself so that the message loop
211 // exists when the dialog is closed by some other means than
212 // |Cancel| or |Accept|.
213 anchor = dialog->GetWidget()->GetNativeWindow();
214 client = aura::client::GetDispatcherClient(anchor->GetRootWindow());
216 client->RunWithDispatcher(dialog.get(), anchor);
217 return dialog->result();
220 } // namespace
222 MessageBoxResult ShowMessageBox(gfx::NativeWindow parent,
223 const base::string16& title,
224 const base::string16& message,
225 MessageBoxType type) {
226 return ShowMessageBoxImpl(
227 parent, title, message, type, base::string16(), base::string16());
230 MessageBoxResult ShowMessageBoxWithButtonText(gfx::NativeWindow parent,
231 const base::string16& title,
232 const base::string16& message,
233 const base::string16& yes_text,
234 const base::string16& no_text) {
235 return ShowMessageBoxImpl(
236 parent, title, message, MESSAGE_BOX_TYPE_QUESTION, yes_text, no_text);
239 } // namespace chrome