42035321cad6bcddc7ee4d71f3243e97cfe9d482
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / simple_message_box_views.cc
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.
4
5 #include "chrome/browser/ui/simple_message_box.h"
6
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/ui/views/constrained_window_views.h"
11 #include "grit/generated_resources.h"
12 #include "ui/aura/window.h"
13 #include "ui/base/l10n/l10n_util.h"
14 #include "ui/gfx/native_widget_types.h"
15 #include "ui/views/controls/message_box_view.h"
16 #include "ui/views/widget/widget.h"
17 #include "ui/views/window/dialog_delegate.h"
18 #include "ui/wm/public/dispatcher_client.h"
19
20 #if defined(OS_WIN)
21 #include "ui/base/win/message_box_win.h"
22 #include "ui/views/win/hwnd_util.h"
23 #endif
24
25 namespace chrome {
26
27 namespace {
28
29 class SimpleMessageBoxViews : public views::DialogDelegate {
30  public:
31   SimpleMessageBoxViews(const base::string16& title,
32                         const base::string16& message,
33                         MessageBoxType type,
34                         const base::string16& yes_text,
35                         const base::string16& no_text,
36                         MessageBoxResult* result);
37   virtual ~SimpleMessageBoxViews();
38
39   // Overridden from views::DialogDelegate:
40   virtual int GetDialogButtons() const OVERRIDE;
41   virtual base::string16 GetDialogButtonLabel(
42       ui::DialogButton button) const OVERRIDE;
43   virtual bool Cancel() OVERRIDE;
44   virtual bool Accept() OVERRIDE;
45
46   // Overridden from views::WidgetDelegate:
47   virtual base::string16 GetWindowTitle() const OVERRIDE;
48   virtual void DeleteDelegate() OVERRIDE;
49   virtual ui::ModalType GetModalType() const OVERRIDE;
50   virtual views::View* GetContentsView() OVERRIDE;
51   virtual views::Widget* GetWidget() OVERRIDE;
52   virtual const views::Widget* GetWidget() const OVERRIDE;
53
54  private:
55
56   // This terminates the nested message-loop.
57   void Done();
58
59   const base::string16 window_title_;
60   const MessageBoxType type_;
61   base::string16 yes_text_;
62   base::string16 no_text_;
63   MessageBoxResult* result_;
64   views::MessageBoxView* message_box_view_;
65
66   DISALLOW_COPY_AND_ASSIGN(SimpleMessageBoxViews);
67 };
68
69 ////////////////////////////////////////////////////////////////////////////////
70 // SimpleMessageBoxViews, public:
71
72 SimpleMessageBoxViews::SimpleMessageBoxViews(const base::string16& title,
73                                              const base::string16& message,
74                                              MessageBoxType type,
75                                              const base::string16& yes_text,
76                                              const base::string16& no_text,
77                                              MessageBoxResult* result)
78     : window_title_(title),
79       type_(type),
80       yes_text_(yes_text),
81       no_text_(no_text),
82       result_(result),
83       message_box_view_(new views::MessageBoxView(
84           views::MessageBoxView::InitParams(message))) {
85   CHECK(result_);
86   if (yes_text_.empty()) {
87     if (type_ == MESSAGE_BOX_TYPE_QUESTION)
88       yes_text_ =
89           l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_YES_BUTTON_LABEL);
90     else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
91       yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
92     else
93       yes_text_ = l10n_util::GetStringUTF16(IDS_OK);
94   }
95
96   if (no_text_.empty()) {
97     if (type_ == MESSAGE_BOX_TYPE_QUESTION)
98       no_text_ =
99           l10n_util::GetStringUTF16(IDS_CONFIRM_MESSAGEBOX_NO_BUTTON_LABEL);
100     else if (type_ == MESSAGE_BOX_TYPE_OK_CANCEL)
101       no_text_ = l10n_util::GetStringUTF16(IDS_CANCEL);
102   }
103 }
104
105 SimpleMessageBoxViews::~SimpleMessageBoxViews() {
106 }
107
108 int SimpleMessageBoxViews::GetDialogButtons() const {
109   if (type_ == MESSAGE_BOX_TYPE_QUESTION ||
110       type_ == MESSAGE_BOX_TYPE_OK_CANCEL) {
111     return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
112   }
113
114   return ui::DIALOG_BUTTON_OK;
115 }
116
117 base::string16 SimpleMessageBoxViews::GetDialogButtonLabel(
118     ui::DialogButton button) const {
119   if (button == ui::DIALOG_BUTTON_CANCEL)
120     return no_text_;
121   return yes_text_;
122 }
123
124 bool SimpleMessageBoxViews::Cancel() {
125   *result_ = MESSAGE_BOX_RESULT_NO;
126   Done();
127   return true;
128 }
129
130 bool SimpleMessageBoxViews::Accept() {
131   *result_ = MESSAGE_BOX_RESULT_YES;
132   Done();
133   return true;
134 }
135
136 base::string16 SimpleMessageBoxViews::GetWindowTitle() const {
137   return window_title_;
138 }
139
140 void SimpleMessageBoxViews::DeleteDelegate() {
141   delete this;
142 }
143
144 ui::ModalType SimpleMessageBoxViews::GetModalType() const {
145   return ui::MODAL_TYPE_WINDOW;
146 }
147
148 views::View* SimpleMessageBoxViews::GetContentsView() {
149   return message_box_view_;
150 }
151
152 views::Widget* SimpleMessageBoxViews::GetWidget() {
153   return message_box_view_->GetWidget();
154 }
155
156 const views::Widget* SimpleMessageBoxViews::GetWidget() const {
157   return message_box_view_->GetWidget();
158 }
159
160 ////////////////////////////////////////////////////////////////////////////////
161 // SimpleMessageBoxViews, private:
162
163 void SimpleMessageBoxViews::Done() {
164   aura::Window* window = GetWidget()->GetNativeView();
165   aura::client::DispatcherClient* client =
166       aura::client::GetDispatcherClient(window->GetRootWindow());
167   client->QuitNestedMessageLoop();
168 }
169
170 #if defined(OS_WIN)
171 UINT GetMessageBoxFlagsFromType(MessageBoxType type) {
172   UINT flags = MB_SETFOREGROUND;
173   switch (type) {
174     case MESSAGE_BOX_TYPE_INFORMATION:
175       return flags | MB_OK | MB_ICONINFORMATION;
176     case MESSAGE_BOX_TYPE_WARNING:
177       return flags | MB_OK | MB_ICONWARNING;
178     case MESSAGE_BOX_TYPE_QUESTION:
179       return flags | MB_YESNO | MB_ICONQUESTION;
180     case MESSAGE_BOX_TYPE_OK_CANCEL:
181       return flags | MB_OKCANCEL | MB_ICONWARNING;
182   }
183   NOTREACHED();
184   return flags | MB_OK | MB_ICONWARNING;
185 }
186 #endif
187
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) {
194 #if defined(OS_WIN)
195   // GPU-based dialogs can't be used early on; fallback to a Windows MessageBox.
196   if (!base::MessageLoop::current()->is_running()) {
197     int result = ui::MessageBox(views::HWNDForNativeWindow(parent), message,
198                                 title, GetMessageBoxFlagsFromType(type));
199     return (result == IDYES || result == IDOK) ?
200         MESSAGE_BOX_RESULT_YES : MESSAGE_BOX_RESULT_NO;
201   }
202 #endif
203
204   MessageBoxResult result = MESSAGE_BOX_RESULT_NO;
205   SimpleMessageBoxViews* dialog = new SimpleMessageBoxViews(
206       title, message, type, yes_text, no_text, &result);
207   CreateBrowserModalDialogViews(dialog, parent)->Show();
208
209   // Use the widget's window itself so that the message loop
210   // exists when the dialog is closed by some other means than
211   // |Cancel| or |Accept|.
212   aura::Window* anchor = dialog->GetWidget()->GetNativeWindow();
213   aura::client::DispatcherClient* client =
214       aura::client::GetDispatcherClient(anchor->GetRootWindow());
215   client->RunWithDispatcher(NULL);
216   // NOTE: |dialog| will have been deleted by the time control returns here.
217
218   return result;
219 }
220
221 }  // namespace
222
223 MessageBoxResult ShowMessageBox(gfx::NativeWindow parent,
224                                 const base::string16& title,
225                                 const base::string16& message,
226                                 MessageBoxType type) {
227   return ShowMessageBoxImpl(
228       parent, title, message, type, base::string16(), base::string16());
229 }
230
231 MessageBoxResult ShowMessageBoxWithButtonText(gfx::NativeWindow parent,
232                                               const base::string16& title,
233                                               const base::string16& message,
234                                               const base::string16& yes_text,
235                                               const base::string16& no_text) {
236   return ShowMessageBoxImpl(
237       parent, title, message, MESSAGE_BOX_TYPE_QUESTION, yes_text, no_text);
238 }
239
240 }  // namespace chrome