- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / simple_web_view_dialog.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/chromeos/login/simple_web_view_dialog.h"
6
7 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/chromeos/login/captive_portal_window_proxy.h"
13 #include "chrome/browser/chromeos/login/helper.h"
14 #include "chrome/browser/command_updater.h"
15 #include "chrome/browser/password_manager/password_manager.h"
16 #include "chrome/browser/password_manager/password_manager_delegate_impl.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
20 #include "chrome/browser/ui/toolbar/toolbar_model_impl.h"
21 #include "chrome/browser/ui/view_ids.h"
22 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
23 #include "chrome/browser/ui/views/reload_button.h"
24 #include "content/public/browser/navigation_controller.h"
25 #include "content/public/browser/navigation_entry.h"
26 #include "content/public/browser/web_contents.h"
27 #include "grit/generated_resources.h"
28 #include "grit/theme_resources.h"
29 #include "ipc/ipc_message.h"
30 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/base/theme_provider.h"
32 #include "ui/views/background.h"
33 #include "ui/views/controls/webview/webview.h"
34 #include "ui/views/layout/grid_layout.h"
35 #include "ui/views/layout/layout_constants.h"
36 #include "ui/views/view.h"
37 #include "ui/views/widget/widget.h"
38
39 using content::WebContents;
40 using views::GridLayout;
41
42 namespace {
43
44 const int kLocationBarHeight = 35;
45
46 // Margin between screen edge and SimpleWebViewDialog border.
47 const int kExternalMargin = 60;
48
49 // Margin between WebView and SimpleWebViewDialog border.
50 const int kInnerMargin = 2;
51
52 class ToolbarRowView : public views::View {
53  public:
54   ToolbarRowView() {
55     set_background(views::Background::CreateSolidBackground(
56         SkColorSetRGB(0xbe, 0xbe, 0xbe)));
57   }
58
59   virtual ~ToolbarRowView() {}
60
61   void Init(views::View* back,
62             views::View* forward,
63             views::View* reload,
64             views::View* location_bar) {
65     GridLayout* layout = new GridLayout(this);
66     SetLayoutManager(layout);
67
68     // Back button.
69     views::ColumnSet* column_set = layout->AddColumnSet(0);
70     column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
71                           GridLayout::USE_PREF, 0, 0);
72     column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
73     // Forward button.
74     column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
75                           GridLayout::USE_PREF, 0, 0);
76     column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
77     // Reload button.
78     column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
79                           GridLayout::USE_PREF, 0, 0);
80     column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
81     // Location bar.
82     column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
83                           GridLayout::FIXED, kLocationBarHeight, 0);
84     column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
85
86     layout->StartRow(0, 0);
87     layout->AddView(back);
88     layout->AddView(forward);
89     layout->AddView(reload);
90     layout->AddView(location_bar);
91   }
92
93  private:
94   DISALLOW_COPY_AND_ASSIGN(ToolbarRowView);
95 };
96
97 }  // namespace
98
99 namespace chromeos {
100
101 // Stub implementation of ContentSettingBubbleModelDelegate.
102 class StubBubbleModelDelegate : public ContentSettingBubbleModelDelegate {
103  public:
104   StubBubbleModelDelegate() {}
105   virtual ~StubBubbleModelDelegate() {}
106
107   // ContentSettingBubbleModelDelegate implementation:
108   virtual void ShowCollectedCookiesDialog(
109       content::WebContents* web_contents) OVERRIDE {
110   }
111
112   virtual void ShowContentSettingsPage(ContentSettingsType type) OVERRIDE {
113   }
114
115  private:
116   DISALLOW_COPY_AND_ASSIGN(StubBubbleModelDelegate);
117 };
118
119 // SimpleWebViewDialog class ---------------------------------------------------
120
121 SimpleWebViewDialog::SimpleWebViewDialog(Profile* profile)
122     : profile_(profile),
123       back_(NULL),
124       forward_(NULL),
125       reload_(NULL),
126       location_bar_(NULL),
127       web_view_(NULL),
128       bubble_model_delegate_(new StubBubbleModelDelegate) {
129   command_updater_.reset(new CommandUpdater(this));
130   command_updater_->UpdateCommandEnabled(IDC_BACK, true);
131   command_updater_->UpdateCommandEnabled(IDC_FORWARD, true);
132   command_updater_->UpdateCommandEnabled(IDC_STOP, true);
133   command_updater_->UpdateCommandEnabled(IDC_RELOAD, true);
134   command_updater_->UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
135   command_updater_->UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, true);
136 }
137
138 SimpleWebViewDialog::~SimpleWebViewDialog() {
139   if (web_view_container_.get()) {
140     // WebView can't be deleted immediately, because it could be on the stack.
141     web_view_->web_contents()->SetDelegate(NULL);
142     base::MessageLoop::current()->DeleteSoon(
143         FROM_HERE, web_view_container_.release());
144   }
145 }
146
147 void SimpleWebViewDialog::StartLoad(const GURL& url) {
148   if (!web_view_container_.get())
149     web_view_container_.reset(new views::WebView(profile_));
150   web_view_ = web_view_container_.get();
151   web_view_->GetWebContents()->SetDelegate(this);
152   web_view_->LoadInitialURL(url);
153
154   WebContents* web_contents = web_view_->GetWebContents();
155   DCHECK(web_contents);
156
157   // Create the password manager that is needed for the proxy.
158   PasswordManagerDelegateImpl::CreateForWebContents(web_contents);
159   PasswordManager::CreateForWebContentsAndDelegate(
160       web_contents, PasswordManagerDelegateImpl::FromWebContents(web_contents));
161 }
162
163 void SimpleWebViewDialog::Init() {
164   toolbar_model_.reset(new ToolbarModelImpl(this));
165
166   set_background(views::Background::CreateSolidBackground(SK_ColorWHITE));
167
168   // Back/Forward buttons.
169   back_ = new views::ImageButton(this);
170   back_->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON |
171                                      ui::EF_MIDDLE_MOUSE_BUTTON);
172   back_->set_tag(IDC_BACK);
173   back_->SetImageAlignment(views::ImageButton::ALIGN_RIGHT,
174                            views::ImageButton::ALIGN_TOP);
175   back_->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_BACK));
176   back_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK));
177   back_->set_id(VIEW_ID_BACK_BUTTON);
178
179   forward_ = new views::ImageButton(this);
180   forward_->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON |
181                                         ui::EF_MIDDLE_MOUSE_BUTTON);
182   forward_->set_tag(IDC_FORWARD);
183   forward_->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_FORWARD));
184   forward_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_FORWARD));
185   forward_->set_id(VIEW_ID_FORWARD_BUTTON);
186
187   // Location bar.
188   location_bar_ = new LocationBarView(NULL, profile_, command_updater_.get(),
189                                       this, true);
190
191   // Reload button.
192   reload_ = new ReloadButton(location_bar_, command_updater_.get());
193   reload_->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON |
194                                        ui::EF_MIDDLE_MOUSE_BUTTON);
195   reload_->set_tag(IDC_RELOAD);
196   reload_->SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_RELOAD));
197   reload_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_RELOAD));
198   reload_->set_id(VIEW_ID_RELOAD_BUTTON);
199
200   LoadImages();
201
202   // Use separate view to setup custom background.
203   ToolbarRowView* toolbar_row = new ToolbarRowView;
204   toolbar_row->Init(back_, forward_, reload_, location_bar_);
205
206   // Layout.
207   GridLayout* layout = new GridLayout(this);
208   SetLayoutManager(layout);
209
210   views::ColumnSet* column_set = layout->AddColumnSet(0);
211   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
212                         GridLayout::FIXED, 0, 0);
213
214   column_set = layout->AddColumnSet(1);
215   column_set->AddPaddingColumn(0, kInnerMargin);
216   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
217                         GridLayout::FIXED, 0, 0);
218   column_set->AddPaddingColumn(0, kInnerMargin);
219
220   // Setup layout rows.
221   layout->StartRow(0, 0);
222   layout->AddView(toolbar_row);
223
224   layout->AddPaddingRow(0, kInnerMargin);
225
226   layout->StartRow(1, 1);
227   layout->AddView(web_view_container_.release());
228   layout->AddPaddingRow(0, kInnerMargin);
229
230   location_bar_->Init();
231   UpdateReload(web_view_->web_contents()->IsLoading(), true);
232
233   gfx::Rect bounds(CalculateScreenBounds(gfx::Size()));
234   bounds.Inset(kExternalMargin, kExternalMargin);
235   layout->set_minimum_size(bounds.size());
236
237   Layout();
238 }
239
240 void SimpleWebViewDialog::Layout() {
241   views::WidgetDelegateView::Layout();
242 }
243
244 views::View* SimpleWebViewDialog::GetContentsView() {
245   return this;
246 }
247
248 views::View* SimpleWebViewDialog::GetInitiallyFocusedView() {
249   return web_view_;
250 }
251
252 void SimpleWebViewDialog::ButtonPressed(views::Button* sender,
253                                         const ui::Event& event) {
254   command_updater_->ExecuteCommand(sender->tag());
255 }
256
257 void SimpleWebViewDialog::NavigationStateChanged(
258     const WebContents* source, unsigned changed_flags) {
259   if (location_bar_) {
260     location_bar_->Update(NULL);
261     UpdateButtons();
262   }
263 }
264
265 content::WebContents* SimpleWebViewDialog::OpenURL(
266     const content::OpenURLParams& params) {
267   // As there are no Browsers right now, this could not actually ever work.
268   NOTIMPLEMENTED();
269   return NULL;
270 }
271
272 void SimpleWebViewDialog::LoadingStateChanged(WebContents* source) {
273   bool is_loading = source->IsLoading();
274   UpdateReload(is_loading, false);
275   command_updater_->UpdateCommandEnabled(IDC_STOP, is_loading);
276 }
277
278 WebContents* SimpleWebViewDialog::GetWebContents() {
279   return NULL;
280 }
281
282 ToolbarModel* SimpleWebViewDialog::GetToolbarModel() {
283   return toolbar_model_.get();
284 }
285
286 const ToolbarModel* SimpleWebViewDialog::GetToolbarModel() const {
287   return toolbar_model_.get();
288 }
289
290 InstantController* SimpleWebViewDialog::GetInstant() {
291   return NULL;
292 }
293
294 views::Widget* SimpleWebViewDialog::CreateViewsBubble(
295     views::BubbleDelegateView* bubble_delegate) {
296   return views::BubbleDelegateView::CreateBubble(bubble_delegate);
297 }
298
299 ContentSettingBubbleModelDelegate*
300 SimpleWebViewDialog::GetContentSettingBubbleModelDelegate() {
301   return bubble_model_delegate_.get();
302 }
303
304 void SimpleWebViewDialog::ShowWebsiteSettings(
305     content::WebContents* web_contents,
306     const GURL& url,
307     const content::SSLStatus& ssl) {
308   NOTIMPLEMENTED();
309   // TODO (ygorshenin@,markusheintz@): implement this
310 }
311
312 PageActionImageView* SimpleWebViewDialog::CreatePageActionImageView(
313     LocationBarView* owner,
314     ExtensionAction* action) {
315   // Notreached because SimpleWebViewDialog uses a popup-mode LocationBarView,
316   // and it doesn't create PageActionImageViews.
317   NOTREACHED();
318   return NULL;
319 }
320
321 content::WebContents* SimpleWebViewDialog::GetActiveWebContents() const {
322   return web_view_->web_contents();
323 }
324
325 void SimpleWebViewDialog::ExecuteCommandWithDisposition(
326     int id,
327     WindowOpenDisposition) {
328   WebContents* web_contents = web_view_->web_contents();
329   switch (id) {
330     case IDC_BACK:
331       if (web_contents->GetController().CanGoBack()) {
332         location_bar_->Revert();
333         web_contents->GetController().GoBack();
334       }
335       break;
336     case IDC_FORWARD:
337       if (web_contents->GetController().CanGoForward()) {
338         location_bar_->Revert();
339         web_contents->GetController().GoForward();
340       }
341       break;
342     case IDC_STOP:
343       web_contents->Stop();
344       break;
345     case IDC_RELOAD:
346       // Always reload ignoring cache.
347     case IDC_RELOAD_IGNORING_CACHE:
348     case IDC_RELOAD_CLEARING_CACHE:
349       web_contents->GetController().ReloadIgnoringCache(true);
350       break;
351     default:
352       NOTREACHED();
353   }
354 }
355
356 void SimpleWebViewDialog::LoadImages() {
357   ui::ThemeProvider* tp = GetThemeProvider();
358
359   back_->SetImage(views::CustomButton::STATE_NORMAL,
360                   tp->GetImageSkiaNamed(IDR_BACK));
361   back_->SetImage(views::CustomButton::STATE_HOVERED,
362                   tp->GetImageSkiaNamed(IDR_BACK_H));
363   back_->SetImage(views::CustomButton::STATE_PRESSED,
364                   tp->GetImageSkiaNamed(IDR_BACK_P));
365   back_->SetImage(views::CustomButton::STATE_DISABLED,
366                   tp->GetImageSkiaNamed(IDR_BACK_D));
367
368   forward_->SetImage(views::CustomButton::STATE_NORMAL,
369                      tp->GetImageSkiaNamed(IDR_FORWARD));
370   forward_->SetImage(views::CustomButton::STATE_HOVERED,
371                      tp->GetImageSkiaNamed(IDR_FORWARD_H));
372   forward_->SetImage(views::CustomButton::STATE_PRESSED,
373                      tp->GetImageSkiaNamed(IDR_FORWARD_P));
374   forward_->SetImage(views::CustomButton::STATE_DISABLED,
375                      tp->GetImageSkiaNamed(IDR_FORWARD_D));
376
377   reload_->LoadImages(tp);
378 }
379
380 void SimpleWebViewDialog::UpdateButtons() {
381   const content::NavigationController& navigation_controller =
382       web_view_->web_contents()->GetController();
383   back_->SetEnabled(navigation_controller.CanGoBack());
384   forward_->SetEnabled(navigation_controller.CanGoForward());
385 }
386
387 void SimpleWebViewDialog::UpdateReload(bool is_loading, bool force) {
388   if (reload_) {
389     reload_->ChangeMode(
390         is_loading ? ReloadButton::MODE_STOP : ReloadButton::MODE_RELOAD,
391         force);
392   }
393 }
394
395 }  // namespace chromeos