Fix: SEGFAULT in UBROWSER_GUI_LEVEL_ALL
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / ubrowser / window_ui.cc
1 // Copyright 2014 Samsung Electronics. 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 "window_ui.h"
6
7 #include <assert.h>
8 #include <Elementary.h>
9 #include <EWebKit.h>
10 #include <EWebKit_internal.h>
11 #include <EWebKit_product.h>
12
13 #include "browser.h"
14 #include "logger.h"
15 #include "window.h"
16
17 #include "tizen/system_info.h"
18
19 namespace {
20 static std::string kDefaultNewWindowURL = "http://www.google.com";
21 static double kMinViewScale = 1.0;
22 static double kMaxViewScale = 4.0;
23 static int kNotificationTimeoutSec = 3;
24 }
25
26 WindowUI::WindowUI(Window& window, Browser& browser)
27     : window_(window),
28       browser_(browser),
29       navbar_(nullptr),
30       urlbar_(nullptr),
31       url_entry_(nullptr),
32       stop_reload_button_(nullptr),
33       progress_bar_(nullptr),
34       forward_button_(nullptr),
35       back_button_(nullptr),
36       active_popup_(nullptr),
37       menu_(nullptr),
38 #if BUILDFLAG(IS_TIZEN_TV)
39       should_show_label_(true),
40 #else
41       should_show_label_(browser_.IsDesktop()),
42 #endif
43       is_loading_(false),
44       url_entry_color_() {
45   if (browser_.GetGUILevel() >= Browser::UBROWSER_GUI_LEVEL_URL_ONLY)
46     CreateTopBar();
47   if (browser_.GetGUILevel() >= Browser::UBROWSER_GUI_LEVEL_MINIMAL)
48     CreateBottomBar();
49
50   // TODO: Workaround for http://suprem.sec.samsung.net/jira/browse/TWF-843
51   if (IsTvProfile()) {
52     should_show_label_ = true;
53     Elm_Theme* theme = elm_theme_new();
54     elm_theme_set(theme, "tizen-HD-light");
55     elm_object_theme_set(navbar_, theme);
56     elm_theme_free(theme);
57   }
58 }
59
60 WindowUI::~WindowUI() {
61   if (active_popup_)
62     evas_object_del(active_popup_);
63 }
64
65 void WindowUI::OnURLChanged(const char* url) {
66   log_trace("%s: %s", __PRETTY_FUNCTION__, url);
67   if (url_entry_)
68     elm_object_text_set(url_entry_, url);
69 }
70
71 void WindowUI::OnLoadingStarted() {
72   log_trace("%s", __PRETTY_FUNCTION__);
73   if (progress_bar_)
74     elm_progressbar_pulse(progress_bar_, EINA_TRUE);
75   if (stop_reload_button_) {
76     Evas_Object* icon =
77         elm_object_part_content_get(stop_reload_button_, "icon");
78     elm_icon_standard_set(icon, "close");
79     if (should_show_label_)
80       elm_object_text_set(stop_reload_button_, "Stop");
81   }
82   is_loading_ = true;
83 }
84
85 void WindowUI::OnLoadingFinished() {
86   log_trace("%s", __PRETTY_FUNCTION__);
87   if (progress_bar_)
88     elm_progressbar_pulse(progress_bar_, EINA_FALSE);
89   if (stop_reload_button_) {
90     Evas_Object* icon =
91         elm_object_part_content_get(stop_reload_button_, "icon");
92     elm_icon_standard_set(icon, "refresh");
93     if (should_show_label_)
94       elm_object_text_set(stop_reload_button_, "Reload");
95   }
96   is_loading_ = false;
97 }
98
99 void WindowUI::EnableBackButton(bool enable) {
100   if (back_button_)
101     elm_object_disabled_set(back_button_, !enable);
102 }
103
104 void WindowUI::EnableForwardButton(bool enable) {
105   if (forward_button_)
106     elm_object_disabled_set(forward_button_, !enable);
107 }
108
109 void WindowUI::ShowNotification(const char* text) {
110   log_trace("%s : %s", __PRETTY_FUNCTION__, text);
111   Evas_Object* notification = elm_notify_add(window_.GetEvasObject());
112   elm_notify_timeout_set(notification, kNotificationTimeoutSec);
113   Evas_Object* content = elm_label_add(notification);
114   elm_object_text_set(content, text);
115   elm_object_content_set(notification, content);
116   elm_notify_align_set(notification, 0.5, 0.5);
117   evas_object_show(notification);
118 }
119
120 void WindowUI::CreateTopBar() {
121   urlbar_ = elm_box_add(window_.GetEvasObject());
122   elm_box_horizontal_set(urlbar_, EINA_TRUE);
123   evas_object_size_hint_weight_set(urlbar_, EVAS_HINT_EXPAND, 0.0f);
124   evas_object_size_hint_align_set(urlbar_, EVAS_HINT_FILL, EVAS_HINT_FILL);
125
126   if (browser_.GetGUILevel() >= Browser::UBROWSER_GUI_LEVEL_ALL) {
127     progress_bar_ = elm_progressbar_add(window_.GetEvasObject());
128     elm_object_style_set(progress_bar_, "wheel");
129     elm_progressbar_pulse_set(progress_bar_, EINA_TRUE);
130     elm_progressbar_pulse(progress_bar_, EINA_FALSE);
131     elm_box_pack_end(urlbar_, progress_bar_);
132     evas_object_show(progress_bar_);
133   }
134
135   url_entry_ = elm_entry_add(urlbar_);
136   elm_entry_single_line_set(url_entry_, EINA_TRUE);
137   elm_entry_scrollable_set(url_entry_, EINA_TRUE);
138   elm_entry_input_panel_layout_set(url_entry_, ELM_INPUT_PANEL_LAYOUT_URL);
139   evas_object_size_hint_weight_set(url_entry_, EVAS_HINT_EXPAND, 1.0f);
140   evas_object_size_hint_align_set(url_entry_, EVAS_HINT_FILL, EVAS_HINT_FILL);
141   evas_object_smart_callback_add(url_entry_, "activated", OnURLEntered, this);
142   elm_box_pack_end(urlbar_, url_entry_);
143   evas_object_color_get(url_entry_, &url_entry_color_.r, &url_entry_color_.g,
144                         &url_entry_color_.b, &url_entry_color_.a);
145   evas_object_show(url_entry_);
146
147 #if !ARCH_CPU_RISCV64 // RISC-V Tizen seems to have a broken implementation for elm_separator_add
148   if (browser_.GetGUILevel() >= Browser::UBROWSER_GUI_LEVEL_ALL) {
149     Evas_Object* separator = elm_separator_add(urlbar_);
150     elm_separator_horizontal_set(separator, EINA_TRUE);
151     elm_box_pack_end(urlbar_, separator);
152     evas_object_show(separator);
153   }
154 #endif
155 }
156
157 void WindowUI::CreateBottomBar() {
158   navbar_ = elm_box_add(window_.GetEvasObject());
159   elm_box_horizontal_set(navbar_, EINA_TRUE);
160   elm_box_homogeneous_set(navbar_, EINA_TRUE);
161   evas_object_size_hint_weight_set(navbar_, EVAS_HINT_EXPAND, 0.0f);
162   evas_object_size_hint_align_set(navbar_, EVAS_HINT_FILL, EVAS_HINT_FILL);
163
164   if (browser_.GetGUILevel() >= Browser::UBROWSER_GUI_LEVEL_ALL) {
165     AddButton(navbar_, "file", "New Window", &WindowUI::OnCreateWindow);
166     if (browser_.IsDesktop())
167       AddButton(navbar_, "file", "New Incognito Window",
168                 &WindowUI::OnCreateIncognitoWindow);
169   }
170
171   back_button_ = AddButton(navbar_, "arrow_left", "Back", &WindowUI::OnBack);
172   forward_button_ =
173       AddButton(navbar_, "arrow_right", "Forward", &WindowUI::OnForward);
174   stop_reload_button_ =
175       AddButton(navbar_, "refresh", "Reload", &WindowUI::OnStopOrReload);
176   if (browser_.GetGUILevel() >= Browser::UBROWSER_GUI_LEVEL_ALL)
177     AddButton(navbar_, "arrow_up", "More Actions",
178               &WindowUI::OnShowExtraActionsMenu);
179
180   EnableBackButton(false);
181   EnableForwardButton(false);
182 }
183
184 Evas_Object* WindowUI::AddButton(Evas_Object* parent,
185     const char* icon, const char* label, Evas_Smart_Cb cb) {
186   Evas_Object* bt = elm_button_add(parent);
187   evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
188   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
189   if (label && should_show_label_)
190     elm_object_text_set(bt, label);
191   if (icon) {
192     Evas_Object* icon_elm = elm_icon_add(bt);
193     elm_icon_standard_set(icon_elm, icon);
194     elm_object_part_content_set(bt, "icon", icon_elm);
195   }
196   evas_object_smart_callback_add(bt, "clicked", cb, this);
197   elm_box_pack_end(parent, bt);
198   evas_object_show(bt);
199
200   return bt;
201 }
202
203 namespace {
204
205 void _HideCtxPopup(void* data, Evas_Object* obj, void*) {
206   evas_object_hide(obj);
207 }
208
209 } // namespace
210
211 void WindowUI::CloseMenu() {
212   evas_object_hide(menu_);
213   evas_object_del(menu_);
214   menu_ = 0;
215 }
216
217 Evas_Object* WindowUI::CreateExtraActionsMenu(Evas_Object* parent) {
218   if (menu_) {
219     CloseMenu();
220     return 0;
221   }
222   menu_ =  elm_ctxpopup_add(parent);
223
224   if ((IsMobileProfile() || IsWearableProfile())) {
225     int width;
226     evas_object_geometry_get(parent, 0, 0, &width, 0);
227     evas_object_size_hint_min_set(menu_, width, 0);
228   }
229   evas_object_smart_callback_add(menu_, "dismissed", _HideCtxPopup, NULL);
230
231   if (window_.IsFormProfileEnabled()) {
232     elm_ctxpopup_item_append(menu_, "Disable Form Profile", NULL,
233                              &WindowUI::OnFormProfileChange, this);
234   } else {
235     elm_ctxpopup_item_append(menu_, "Enable Form Profile", NULL,
236                              &WindowUI::OnFormProfileChange, this);
237   }
238
239   if (window_.IsRememberFormDataEnabled()) {
240     elm_ctxpopup_item_append(menu_, "Disable Remember Form Data", NULL,
241                              &WindowUI::OnRememberFormDataChange, this);
242   } else {
243     elm_ctxpopup_item_append(menu_, "Enable Remember Form Data", NULL,
244                              &WindowUI::OnRememberFormDataChange, this);
245   }
246
247   if (window_.IsRememberPasswordEnabled()) {
248     elm_ctxpopup_item_append(menu_, "Disable Remember Password", NULL,
249                              &WindowUI::OnRememberPasswordChange, this);
250   } else {
251     elm_ctxpopup_item_append(menu_, "Enable Remember Password", NULL,
252                              &WindowUI::OnRememberPasswordChange, this);
253   }
254
255   elm_ctxpopup_item_append(menu_, "Override User Agent String", NULL,
256                            &WindowUI::OnUAOverride, this);
257
258   if (browser_.IsDesktop()) {
259     elm_ctxpopup_item_append(menu_, "Show Web Inspector", NULL,
260                              &WindowUI::OnInspectorShow, this);
261   } else {
262     elm_ctxpopup_item_append(menu_, "Start Web Inspector server", NULL,
263                              &WindowUI::OnInspectorServerStart, this);
264   }
265
266   elm_ctxpopup_item_append(menu_, "Use Google data proxy", NULL,
267                            &WindowUI::OnUseGoogleDataProxy, this);
268 #if !BUILDFLAG(IS_TIZEN)
269   elm_ctxpopup_item_append(menu_, "Simulate screen rotation", NULL,
270       &WindowUI::OnRotate, this);
271 #endif
272
273   if (window_.AreTouchEventsEnabled()) {
274     elm_ctxpopup_item_append(menu_, "Enable mouse events", NULL,
275                              &WindowUI::OnSelectMouseInput, this);
276   } else {
277     elm_ctxpopup_item_append(menu_, "Enable touch events", NULL,
278                              &WindowUI::OnSelectTouchInput, this);
279   }
280
281   if (!browser_.IsTracingEnabled()) {
282     elm_ctxpopup_item_append(menu_, "Start tracing", NULL,
283                              &WindowUI::OnStartTracing, this);
284   } else {
285     elm_ctxpopup_item_append(menu_, "Stop tracing", NULL,
286                              &WindowUI::OnStopTracing, this);
287   }
288
289   Ewk_Settings* settings = window_.GetEwkSettings();
290   if (!ewk_settings_auto_fitting_get(settings)) {
291     elm_ctxpopup_item_append(menu_, "Enable auto fitting", NULL,
292                              &WindowUI::OnAutoFittingEnabled, this);
293   } else {
294     elm_ctxpopup_item_append(menu_, "Disable auto fitting", NULL,
295                              &WindowUI::OnAutoFittingDisabled, this);
296   }
297
298   if (!ewk_settings_scripts_can_open_windows_get(settings)) {
299     elm_ctxpopup_item_append(menu_, "Enable js window.open", NULL,
300                              &WindowUI::OnScriptWindowOpenEnabled, this);
301   } else {
302     elm_ctxpopup_item_append(menu_, "Disable js window.open", NULL,
303                              &WindowUI::OnScriptWindowOpenDisabled, this);
304   }
305
306   if (!ewk_settings_form_profile_data_enabled_get(settings) ||
307      !ewk_settings_form_candidate_data_enabled_get(settings)) {
308     elm_ctxpopup_item_append(menu_, "Enable autofill", NULL,
309                              &WindowUI::OnAutoFillEnabled, this);
310   } else {
311     elm_ctxpopup_item_append(menu_, "Disable autofill", NULL,
312                              &WindowUI::OnAutoFillDisabled, this);
313   }
314
315   elm_ctxpopup_item_append(menu_, "Change page zoom level", NULL,
316                            &WindowUI::OnShowZoomPopup, this);
317
318   elm_ctxpopup_item_append(menu_, "Take screenshot async", NULL,
319                            &WindowUI::OnTakeScreenshotAsync, this);
320
321   elm_ctxpopup_item_append(menu_, "Take screenshot sync", NULL,
322                            &WindowUI::OnTakeScreenshotSync, this);
323
324   elm_ctxpopup_item_append(menu_, "Quit", NULL, &WindowUI::Exit, this);
325
326   return menu_;
327 }
328
329 void WindowUI::ShowPermissionPopup(const char* title,
330     const char* description, PermissionCallback cb, void* data) {
331   log_trace("%s: (%s, %s)", __PRETTY_FUNCTION__, title, description);
332
333   Evas_Object* popup = elm_popup_add(window_.GetEvasObject());
334   elm_object_part_text_set(popup, "title,text", title);
335   elm_object_part_text_set(popup, NULL, description);
336   elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
337   active_popup_ = popup;
338
339   Evas_Object* btn = elm_button_add(popup);
340   elm_object_text_set(btn, "Yes");
341   PermissionPopupButtonData* buttonData = new PermissionPopupButtonData;
342   buttonData->callbackData=data;
343   buttonData->callback=cb;
344   buttonData->popupData=this;
345
346   evas_object_smart_callback_add(btn, "clicked", PermissionGranted,
347                                  buttonData);
348   elm_object_part_content_set(popup, "button1", btn);
349
350   btn = elm_button_add(popup);
351   elm_object_text_set(btn, "No");
352   evas_object_smart_callback_add(btn, "clicked", PermissionDeclined,
353                                  buttonData);
354   elm_object_part_content_set(popup, "button2", btn);
355
356   evas_object_show(popup);
357 }
358
359 void WindowUI::OnThemeColorChanged(int r, int g, int b, int a) {
360   log_trace("%s: rgba(%d, %d, %d, %d)", __PRETTY_FUNCTION__, r, g, b, a);
361   if (url_entry_) {
362     // FIXME: For darker colors font color is to close to background color in
363     // entry. It is style dependent, so style modification or change would be
364     // needed to solve that issue.
365     if (a != 0)
366       evas_object_color_set(url_entry_, r, g, b, a);
367     else
368       evas_object_color_set(url_entry_, url_entry_color_.r, url_entry_color_.g,
369                             url_entry_color_.b, url_entry_color_.a);
370   }
371 }
372
373 void WindowUI::PermissionGranted(void* data, Evas_Object* button, void*) {
374   log_trace("%s", __PRETTY_FUNCTION__);
375
376   PermissionPopupButtonData* buttonData =(PermissionPopupButtonData*) data;
377   ClosePopup(buttonData->popupData, NULL, NULL);
378   buttonData->callback(true, buttonData->callbackData);
379   delete buttonData;
380 }
381
382 void WindowUI::PermissionDeclined(void* data, Evas_Object* button, void*) {
383   log_trace("%s", __PRETTY_FUNCTION__);
384
385   PermissionPopupButtonData* buttonData =(PermissionPopupButtonData*) data;
386   ClosePopup(buttonData->popupData, NULL, NULL);
387   buttonData->callback(false, buttonData->callbackData);
388   delete buttonData;
389 }
390
391 void WindowUI::ShowInspectorURLPopup(const char* url) {
392   log_trace("%s : %s", __PRETTY_FUNCTION__, url);
393   Evas_Object* popup = elm_popup_add(window_.GetEvasObject());
394   elm_object_part_text_set(popup, "title,text", url);
395   elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
396   active_popup_ = popup;
397
398   Evas_Object* btn = elm_button_add(popup);
399   elm_object_text_set(btn, "Close");
400   evas_object_smart_callback_add(btn, "clicked", ClosePopup, this);
401   elm_object_part_content_set(popup, "button1", btn);
402
403   evas_object_show(popup);
404 }
405
406 void WindowUI::ShowTextEntryPopup(const char* title,
407                                   const char* initial_content,
408                                   Evas_Smart_Cb cb) {
409   log_trace("%s: (%s, %s)", __PRETTY_FUNCTION__, title, initial_content);
410
411   Evas_Object* popup = elm_popup_add(window_.GetEvasObject());
412   elm_object_part_text_set(popup, "title,text", title);
413   elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
414   active_popup_ = popup;
415
416   Evas_Object* entry = elm_entry_add(popup);
417   elm_entry_single_line_set(entry, EINA_TRUE);
418   elm_entry_scrollable_set(entry, EINA_TRUE);
419   elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_URL);
420   evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0f);
421   evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
422   evas_object_smart_callback_add(
423       entry, "activated", cb,
424       new std::pair<Evas_Object*, WindowUI*>(entry, this));
425
426   elm_object_part_content_set(popup, "default", entry);
427   if (initial_content) {
428     elm_object_text_set(entry, initial_content);
429     elm_entry_cursor_end_set(entry);
430   }
431
432   Evas_Object* btn = elm_button_add(popup);
433   elm_object_text_set(btn, "OK");
434   evas_object_smart_callback_add(
435       btn, "clicked", cb, new std::pair<Evas_Object*, WindowUI*>(entry, this));
436   elm_object_part_content_set(popup, "button1", btn);
437
438   btn = elm_button_add(popup);
439   elm_object_text_set(btn, "Cancel");
440   evas_object_smart_callback_add(btn, "clicked", ClosePopup, this);
441   elm_object_part_content_set(popup, "button2", btn);
442
443   evas_object_show(popup);
444 }
445
446 void WindowUI::OnCreateWindow(void* data, Evas_Object*, void*) {
447   log_trace("%s", __PRETTY_FUNCTION__);
448   WindowUI* thiz = static_cast<WindowUI*>(data);
449   if (thiz->browser_.IsDesktop()) {
450     thiz->browser_.CreateWindow().LoadURL(kDefaultNewWindowURL);
451   } else {
452     thiz->browser_.ActivateToolboxWindow();
453   }
454 }
455
456 void WindowUI::OnCreateIncognitoWindow(void* data, Evas_Object*, void*) {
457   log_trace("%s", __PRETTY_FUNCTION__);
458   WindowUI* thiz = static_cast<WindowUI*>(data);
459   thiz->browser_.CreateWindow(true).LoadURL(kDefaultNewWindowURL);
460 }
461
462 void WindowUI::OnBack(void* data, Evas_Object*, void*) {
463   log_trace("%s", __PRETTY_FUNCTION__);
464   static_cast<WindowUI*>(data)->window_.Back();
465 }
466
467 void WindowUI::OnForward(void* data, Evas_Object*, void*) {
468   log_trace("%s", __PRETTY_FUNCTION__);
469   static_cast<WindowUI*>(data)->window_.Forward();
470 }
471
472 void WindowUI::OnStopOrReload(void* data, Evas_Object*, void*) {
473   log_trace("%s", __PRETTY_FUNCTION__);
474   WindowUI* thiz = static_cast<WindowUI*>(data);
475   if (thiz->is_loading_)
476     thiz->window_.Stop();
477   else
478     thiz->window_.Reload();
479 }
480
481 void WindowUI::OnShowExtraActionsMenu(void* data, Evas_Object* obj, void*) {
482   log_trace("%s", __PRETTY_FUNCTION__);
483   WindowUI* thiz = static_cast<WindowUI*>(data);
484   Evas_Object* popup = thiz->CreateExtraActionsMenu(
485       thiz->window_.GetEvasObject());
486
487   if (!popup)
488     return;
489
490   int x, y;
491   evas_object_geometry_get(obj, &x, &y, 0, 0);
492   evas_object_move(popup, x, y);
493   evas_object_show(popup);
494 }
495
496 void WindowUI::OnURLEntered(void* data, Evas_Object*, void*) {
497   log_trace("%s", __PRETTY_FUNCTION__);
498   WindowUI* thiz = static_cast<WindowUI*>(data);
499   thiz->window_.LoadURL(elm_object_text_get(thiz->url_entry_));
500   elm_object_focus_set(thiz->url_entry_, EINA_FALSE);
501 }
502
503 void WindowUI::OnUAOverride(void* data, Evas_Object* obj, void*) {
504   log_trace("%s", __PRETTY_FUNCTION__);
505   WindowUI* thiz = static_cast<WindowUI*>(data);
506   const char* ua = thiz->window_.GetUserAgent();
507   thiz->ShowTextEntryPopup("User Agent Override", ua,
508                            &WindowUI::OnUAOverrideEntered);
509   thiz->CloseMenu();
510 }
511
512 void WindowUI::OnUAOverrideEntered(void* data, Evas_Object*, void*) {
513   std::pair<Evas_Object*, WindowUI*>* p =
514       static_cast<std::pair<Evas_Object*, WindowUI*>*>(data);
515   p->second->window_.SetUserAgent(elm_object_text_get(p->first));
516   evas_object_del(p->second->active_popup_);
517   p->second->active_popup_ = NULL;
518   delete p;
519 }
520
521 void WindowUI::OnInspectorShow(void* data, Evas_Object* obj, void*) {
522   log_trace("%s", __PRETTY_FUNCTION__);
523   WindowUI* thiz = static_cast<WindowUI*>(data);
524   thiz->browser_.ShowInspectorWindow();
525   thiz->CloseMenu();
526 }
527
528 void WindowUI::OnInspectorServerStart(void* data, Evas_Object* obj, void*) {
529     log_trace("%s", __PRETTY_FUNCTION__);
530     WindowUI* thiz = static_cast<WindowUI*>(data);
531     thiz->browser_.StartInspectorServer();
532     thiz->CloseMenu();
533 }
534
535 void WindowUI::OnUseGoogleDataProxy(void* data, Evas_Object* obj, void*) {
536   log_trace("%s", __PRETTY_FUNCTION__);
537   WindowUI* thiz = static_cast<WindowUI*>(data);
538   ewk_context_proxy_set(ewk_context_default_get(), "compress.googlezip.net:80",
539                         "<local>");
540   thiz->window_.SetGoogleDataProxyHeaders();
541   thiz->CloseMenu();
542 }
543
544 void WindowUI::OnRotate(void* data, Evas_Object* obj, void*) {
545   log_trace("%s", __PRETTY_FUNCTION__);
546   WindowUI* thiz = static_cast<WindowUI*>(data);
547   thiz->window_.FakeRotate();
548   thiz->CloseMenu();
549 }
550
551 void WindowUI::OnSelectMouseInput(void* data, Evas_Object* obj, void*) {
552   log_trace("%s", __PRETTY_FUNCTION__);
553   WindowUI* thiz = static_cast<WindowUI*>(data);
554   thiz->window_.EnableTouchEvents(false);
555   thiz->window_.EnableMouseEvents(true);
556   thiz->ShowNotification("Mouse events enabled");
557   thiz->CloseMenu();
558 }
559
560 void WindowUI::OnSelectTouchInput(void* data, Evas_Object* obj, void*) {
561   log_trace("%s", __PRETTY_FUNCTION__);
562   WindowUI* thiz = static_cast<WindowUI*>(data);
563   thiz->window_.EnableTouchEvents(true);
564   thiz->window_.EnableMouseEvents(false);
565   thiz->ShowNotification("Touch events enabled");
566   thiz->CloseMenu();
567 }
568
569 void WindowUI::OnStartTracing(void* data, Evas_Object* obj, void*) {
570   log_trace("%s", __PRETTY_FUNCTION__);
571   WindowUI* thiz = static_cast<WindowUI*>(data);
572   thiz->browser_.StartTracing();
573   thiz->CloseMenu();
574   thiz->ShowNotification("Tracing started");
575 }
576
577 void WindowUI::OnStopTracing(void* data, Evas_Object* obj, void*) {
578   log_trace("%s", __PRETTY_FUNCTION__);
579   WindowUI* thiz = static_cast<WindowUI*>(data);
580   thiz->browser_.StopTracing();
581   thiz->CloseMenu();
582   thiz->ShowNotification("Tracing finished");
583 }
584
585 void WindowUI::OnAutoFittingEnabled(void* data, Evas_Object* obj, void*) {
586   log_trace("%s", __PRETTY_FUNCTION__);
587   WindowUI* thiz = static_cast<WindowUI*>(data);
588   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
589   ewk_settings_auto_fitting_set(settings, true);
590   thiz->CloseMenu();
591   thiz->ShowNotification("Auto fitting enabled");
592 }
593
594 void WindowUI::OnAutoFittingDisabled(void* data, Evas_Object* obj, void*) {
595   log_trace("%s", __PRETTY_FUNCTION__);
596   WindowUI* thiz = static_cast<WindowUI*>(data);
597   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
598   ewk_settings_auto_fitting_set(settings, false);
599   thiz->CloseMenu();
600   thiz->ShowNotification("Auto fitting disabled");
601 }
602
603 void WindowUI::OnAutoFillEnabled(void* data, Evas_Object* obj, void*) {
604   log_trace("%s", __PRETTY_FUNCTION__);
605   WindowUI* thiz = static_cast<WindowUI*>(data);
606   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
607   ewk_settings_form_profile_data_enabled_set(settings, true);
608   ewk_settings_form_candidate_data_enabled_set(settings, true);
609   thiz->CloseMenu();
610   thiz->ShowNotification("Autofill enabled");
611 }
612
613 void WindowUI::OnAutoFillDisabled(void* data, Evas_Object* obj, void*) {
614   log_trace("%s", __PRETTY_FUNCTION__);
615   WindowUI* thiz = static_cast<WindowUI*>(data);
616   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
617   ewk_settings_form_profile_data_enabled_set(settings, false);
618   ewk_settings_form_candidate_data_enabled_set(settings, false);
619   thiz->CloseMenu();
620   thiz->ShowNotification("Autofill disabled");
621 }
622
623 void WindowUI::OnScriptWindowOpenEnabled(void* data, Evas_Object* obj, void*) {
624   log_trace("%s", __PRETTY_FUNCTION__);
625   WindowUI* thiz = static_cast<WindowUI*>(data);
626   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
627   ewk_settings_scripts_can_open_windows_set(settings, true);
628   thiz->CloseMenu();
629   thiz->ShowNotification("JS window.open enabled");
630 }
631
632 void WindowUI::OnScriptWindowOpenDisabled(void* data, Evas_Object* obj, void*) {
633   log_trace("%s", __PRETTY_FUNCTION__);
634   WindowUI* thiz = static_cast<WindowUI*>(data);
635   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
636   ewk_settings_scripts_can_open_windows_set(settings, false);
637   thiz->CloseMenu();
638   thiz->ShowNotification("JS window.open disabled");
639 }
640
641 void WindowUI::ClosePopup(void* data, Evas_Object*, void*) {
642   WindowUI* thiz = static_cast<WindowUI*>(data);
643   evas_object_del(thiz->active_popup_);
644   thiz->active_popup_ = NULL;
645 }
646
647 void WindowUI::ClosePopup() {
648   if (active_popup_) {
649     evas_object_del(active_popup_);
650     active_popup_ = NULL;
651   }
652 }
653
654 void WindowUI::OnShowZoomPopup(void* data, Evas_Object* obj, void*) {
655   log_trace("%s", __PRETTY_FUNCTION__);
656   WindowUI* thiz = static_cast<WindowUI*>(data);
657
658   Evas_Object* popup = elm_popup_add(thiz->window_.GetEvasObject());
659   elm_object_part_text_set(popup, "title,text", "Change page zoom level");
660   elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
661   thiz->active_popup_ = popup;
662   Evas_Object* btn = elm_button_add(popup);
663
664   Evas_Object* slider = elm_slider_add(popup);
665   thiz->window_.GetScaleRange(&kMinViewScale, &kMaxViewScale);
666   elm_slider_min_max_set(slider, kMinViewScale, kMaxViewScale);
667   elm_slider_value_set(slider, thiz->window_.GetScale());
668   elm_slider_indicator_format_set(slider, "%1.2f");
669   elm_slider_indicator_show_set(slider, EINA_TRUE);
670   evas_object_smart_callback_add(slider, "changed", &OnZoomChanged, thiz);
671   elm_object_part_content_set(popup, "default", slider);
672
673   elm_object_text_set(btn, "Close");
674   evas_object_smart_callback_add(btn, "clicked", ClosePopup, thiz);
675   elm_object_part_content_set(popup, "button1", btn);
676
677   evas_object_show(popup);
678   thiz->CloseMenu();
679 }
680
681 void WindowUI::OnTakeScreenshotAsync(void* data, Evas_Object* obj, void*) {
682   log_trace("%s", __PRETTY_FUNCTION__);
683   WindowUI* thiz = static_cast<WindowUI*>(data);
684   thiz->window_.TakeScreenshot(false);
685   thiz->CloseMenu();
686 }
687
688 void WindowUI::OnTakeScreenshotSync(void* data, Evas_Object* obj, void*) {
689   log_trace("%s", __PRETTY_FUNCTION__);
690   WindowUI* thiz = static_cast<WindowUI*>(data);
691   thiz->window_.TakeScreenshot(true);
692   thiz->CloseMenu();
693 }
694
695 void WindowUI::OnZoomChanged(void* data, Evas_Object* obj, void*) {
696   log_trace("%s", __PRETTY_FUNCTION__);
697   WindowUI* thiz = static_cast<WindowUI*>(data);
698   thiz->window_.SetScale(elm_slider_value_get(obj));
699 }
700
701 void WindowUI::OnRememberFormDataChange(void* data, Evas_Object* obj, void*) {
702   log_trace("%s", __PRETTY_FUNCTION__);
703   WindowUI* thiz = static_cast<WindowUI*>(data);
704   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
705   if (thiz->window_.IsRememberFormDataEnabled()) {
706     ewk_settings_form_candidate_data_enabled_set(settings, false);
707     thiz->ShowNotification("Remember Form Data disabled");
708   } else {
709     ewk_settings_form_candidate_data_enabled_set(settings, true);
710     thiz->ShowNotification("Remember Form Data enabled");
711   }
712   thiz->CloseMenu();
713 }
714
715 void WindowUI::OnRememberPasswordChange(void* data, Evas_Object* obj, void*) {
716   log_trace("%s", __PRETTY_FUNCTION__);
717   WindowUI* thiz = static_cast<WindowUI*>(data);
718   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
719   if (thiz->window_.IsRememberPasswordEnabled()) {
720     ewk_settings_autofill_password_form_enabled_set(settings, false);
721     thiz->ShowNotification("Remember Password disabled");
722   } else {
723     ewk_settings_autofill_password_form_enabled_set(settings, true);
724     thiz->ShowNotification("Remember Password enabled");
725   }
726   thiz->CloseMenu();
727 }
728
729 void WindowUI::OnFormProfileChange(void* data, Evas_Object* obj, void*) {
730   log_trace("%s", __PRETTY_FUNCTION__);
731   WindowUI* thiz = static_cast<WindowUI*>(data);
732   Ewk_Settings* settings = thiz->window_.GetEwkSettings();
733   if (thiz->window_.IsFormProfileEnabled()) {
734     ewk_settings_form_profile_data_enabled_set(settings, false);
735     thiz->ShowNotification("Form Profile disabled");
736   } else {
737     ewk_settings_form_profile_data_enabled_set(settings, true);
738     thiz->ShowNotification("Form Profile enabled");
739   }
740   thiz->CloseMenu();
741 }
742
743 void WindowUI::Exit(void* data, Evas_Object*, void*) {
744   WindowUI* thiz = static_cast<WindowUI*>(data);
745   thiz->window_.Exit();
746 }