2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <Elementary.h>
20 #include "BrowserLogger.h"
21 #include "MenuButton.h"
23 #include <boost/regex.hpp>
24 #include "BrowserAssert.h"
26 namespace tizen_browser {
29 #define GUIDE_TEXT_FOCUSED "Search or URL"
30 #define GUIDE_TEXT_UNFOCUSED "Search or URL - Press [A] to enter"
32 const std::string keynameSelect = "Select";
33 const std::string keynameClear = "Clear";
34 const std::string keynameKP_Enter = "KP_Enter";
35 const std::string keynameReturn = "Return";
36 const std::string keynameEsc = "XF86Back";
42 , m_entry_layout(NULL)
43 , m_entrySelectedAllFirst(false)
45 std::string edjFilePath = EDJE_DIR;
46 edjFilePath.append("WebPageUI/URIEntry.edj");
47 elm_theme_extension_add(NULL, edjFilePath.c_str());
53 void URIEntry::init(Evas_Object* parent)
58 Evas_Object* URIEntry::getContent()
60 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
63 if (!m_entry_layout) {
64 m_entry_layout = elm_layout_add(m_parent);
65 std::string edjFilePath = EDJE_DIR;
66 edjFilePath.append("WebPageUI/URIEntry.edj");
67 Eina_Bool layoutSetResult = elm_layout_file_set(m_entry_layout, edjFilePath.c_str(), "uri_entry_layout");
69 throw std::runtime_error("Layout file not found: " + edjFilePath);
71 m_entry = elm_entry_add(m_entry_layout);
72 elm_object_style_set(m_entry, "uri_entry");
74 elm_entry_single_line_set(m_entry, EINA_TRUE);
75 elm_entry_scrollable_set(m_entry, EINA_TRUE);
76 elm_entry_input_panel_layout_set(m_entry, ELM_INPUT_PANEL_LAYOUT_URL);
78 setUrlGuideText(GUIDE_TEXT_UNFOCUSED);
80 evas_object_smart_callback_add(m_entry, "activated", URIEntry::activated, this);
81 evas_object_smart_callback_add(m_entry, "aborted", URIEntry::aborted, this);
82 evas_object_smart_callback_add(m_entry, "preedit,changed", URIEntry::preeditChange, this);
83 evas_object_smart_callback_add(m_entry, "changed", URIEntry::_uri_entry_editing_changed, this);
84 evas_object_smart_callback_add(m_entry, "changed,user", URIEntry::_uri_entry_editing_changed_user, this);
85 evas_object_smart_callback_add(m_entry, "focused", URIEntry::focused, this);
86 evas_object_smart_callback_add(m_entry, "unfocused", URIEntry::unfocused, this);
87 evas_object_smart_callback_add(m_entry, "clicked", _uri_entry_clicked, this);
88 evas_object_event_callback_priority_add(m_entry, EVAS_CALLBACK_KEY_DOWN, 2 * EVAS_CALLBACK_PRIORITY_BEFORE, URIEntry::_fixed_entry_key_down_handler, this);
90 elm_object_part_content_set(m_entry_layout, "uri_entry_swallow", m_entry);
92 m_entryBtn = elm_button_add(m_entry_layout);
94 evas_object_smart_callback_add(m_entryBtn, "focused", URIEntry::focusedBtn, this);
95 evas_object_smart_callback_add(m_entryBtn, "unfocused", URIEntry::unfocusedBtn, this);
97 elm_object_style_set(m_entryBtn, "entry_btn");
98 evas_object_smart_callback_add(m_entryBtn, "clicked", _uri_entry_btn_clicked, this);
100 elm_object_part_content_set(m_entry_layout, "uri_entry_btn", m_entryBtn);
102 return m_entry_layout;
105 void URIEntry::changeUri(const std::string& newUri)
107 BROWSER_LOGD("%s: newUri=%s", __func__, newUri.c_str());
110 elm_entry_entry_set(m_entry, elm_entry_utf8_to_markup(""));
111 m_pageTitle = std::string();
115 void URIEntry::setFavIcon(std::shared_ptr< tizen_browser::tools::BrowserImage > favicon)
117 BROWSER_LOGD("[%s:%d] faviconType:%d ", __PRETTY_FUNCTION__, __LINE__, favicon->imageType);
118 if (favicon->imageType != tools::BrowserImage::ImageTypeNoImage) {
119 m_favicon = tizen_browser::tools::EflTools::getEvasImage(favicon, m_entry_layout);
120 evas_object_image_fill_set(m_favicon, 0, 0, 36, 36);
121 evas_object_resize(m_favicon, 36, 36);
122 elm_object_part_content_set(m_entry_layout, "fav_icon", m_favicon);
129 void URIEntry::setCurrentFavIcon()
131 m_currentIconType = IconTypeFav;
132 elm_object_signal_emit(m_entry_layout, "show_favicon", "model");
135 void URIEntry::setSearchIcon()
137 m_currentIconType = IconTypeSearch;
138 elm_object_signal_emit(m_entry_layout, "set_search_icon", "model");
141 void URIEntry::setDocIcon()
143 m_currentIconType = IconTypeDoc;
144 elm_object_signal_emit(m_entry_layout, "set_doc_icon", "model");
147 void URIEntry::setPageTitle(const std::string& title)
149 BROWSER_LOGD("%s", __func__);
151 elm_entry_entry_set(m_entry, elm_entry_utf8_to_markup(m_pageTitle.c_str()));
154 void URIEntry::setURI(const std::string& uri)
156 BROWSER_LOGD("%s, URI: %s", __func__, uri.c_str());
160 void URIEntry::showPageTitle()
162 BROWSER_LOGD("%s, Page title: %s", __func__, m_pageTitle.c_str());
163 if (!m_pageTitle.empty())
164 elm_entry_entry_set(m_entry, elm_entry_utf8_to_markup(m_pageTitle.c_str()));
165 else if (!m_URI.empty())
166 elm_entry_entry_set(m_entry, elm_entry_utf8_to_markup(m_URI.c_str()));
168 elm_entry_entry_set(m_entry, elm_entry_utf8_to_markup(""));
171 URIEntry::IconType URIEntry::getCurrentIconTyep()
173 return m_currentIconType;
176 void URIEntry::selectWholeText()
178 m_oryginalEntryText = elm_entry_markup_to_utf8(elm_entry_entry_get(m_entry));
179 if (!m_entrySelectedAllFirst && !m_oryginalEntryText.empty()) {
180 elm_entry_select_all(m_entry);
181 elm_entry_cursor_end_set(m_entry);
182 m_entrySelectedAllFirst = true;
186 void URIEntry::_uri_entry_clicked(void* data, Evas_Object* /* obj */, void* /* event_info */)
188 URIEntry* self = static_cast<URIEntry*>(data);
189 self->selectWholeText();
192 void URIEntry::_uri_entry_btn_clicked(void* data, Evas_Object* /*obj*/, void* /*event_info*/)
194 URIEntry* self = static_cast<URIEntry*>(data);
195 elm_object_focus_set(self->m_entry, EINA_TRUE);
196 self->selectWholeText();
198 elm_object_signal_emit(self->m_entry_layout, "mouse,in", "over");
201 void URIEntry::activated(void* /* data */, Evas_Object* /* obj */, void* /*event_info*/)
203 BROWSER_LOGD("%s", __func__);
206 void URIEntry::aborted(void* data, Evas_Object* /* obj */, void* /*event_info*/)
208 BROWSER_LOGD("%s", __func__);
209 URIEntry* self = reinterpret_cast<URIEntry*>(data);
210 self->editingCanceled();
213 void URIEntry::preeditChange(void* /* data */, Evas_Object* /* obj */, void* /*event_info*/)
215 BROWSER_LOGD("%s", __func__);
218 void URIEntry::_uri_entry_editing_changed_user(void* data, Evas_Object* /* obj */, void* /*event_info*/)
220 BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
221 URIEntry* self = reinterpret_cast<URIEntry*>(data);
222 std::string entry(elm_entry_markup_to_utf8(elm_entry_entry_get(self->m_entry)));
223 if ((entry.find("http://") == 0)
224 || (entry.find("https://") == 0)
225 || (entry.find(".") != std::string::npos)) {
227 } else {//if(entry.find(" ") != std::string::npos){
228 self->setSearchIcon();
230 self->uriEntryEditingChangedByUser(std::make_shared<std::string>(entry));
233 void URIEntry::_uri_entry_editing_changed(void* data, Evas_Object* /* obj */, void* /* event_info */)
235 URIEntry* self = static_cast<URIEntry*>(data);
236 self->uriEntryEditingChanged();
239 void URIEntry::setUrlGuideText(const char* txt) const
242 elm_object_translatable_part_text_set(m_entry, "elm.guide", txt);
244 elm_object_part_text_set(m_entry, "elm.guide", txt);
248 void URIEntry::unfocused(void* data, Evas_Object*, void*)
250 BROWSER_LOGD("%s", __func__);
251 URIEntry* self = static_cast<URIEntry*>(data);
252 self->m_entrySelectedAllFirst = false;
253 self->setUrlGuideText(GUIDE_TEXT_UNFOCUSED);
254 elm_object_signal_emit(self->m_entry_layout, "mouse,out", "over");
255 elm_entry_entry_set(self->m_entry, elm_entry_utf8_to_markup(self->m_pageTitle.c_str()));
258 void URIEntry::focused(void* data, Evas_Object* /* obj */, void* /* event_info */)
260 URIEntry* self = static_cast<URIEntry*>(data);
261 self->setUrlGuideText(GUIDE_TEXT_FOCUSED);
262 elm_object_signal_emit(self->m_entry_layout, "mouse,in", "over");
263 elm_entry_entry_set(self->m_entry, elm_entry_utf8_to_markup(self->m_URI.c_str()));
264 BROWSER_LOGD("%s, URI: %s", __func__, self->m_URI.c_str());
267 void URIEntry::_fixed_entry_key_down_handler(void* data, Evas* /*e*/, Evas_Object* /*obj*/, void* event_info)
269 BROWSER_LOGD("%s", __func__);
270 Evas_Event_Key_Down* ev = static_cast<Evas_Event_Key_Down*>(event_info);
271 if (!data || !ev || !ev->keyname)
273 URIEntry* self = static_cast<URIEntry*>(data);
275 if (keynameClear == ev->keyname) {
276 elm_entry_entry_set(self->m_entry, "");
279 if (keynameSelect == ev->keyname
280 || keynameReturn == ev->keyname
281 || keynameKP_Enter == ev->keyname) {
282 self->editingCompleted();
285 if (keynameEsc == ev->keyname) {
286 self->editingCanceled();
287 elm_object_focus_set(self->m_entryBtn, EINA_TRUE);
292 void URIEntry::editingCompleted()
294 char* text = elm_entry_markup_to_utf8(elm_entry_entry_get(m_entry));
295 std::string userString(text);
298 elm_entry_input_panel_hide(m_entry);
299 uriChanged(rewriteURI(userString));
300 elm_object_focus_set(m_entryBtn, EINA_TRUE);
303 std::string URIEntry::rewriteURI(const std::string& url)
305 BROWSER_LOGD("%s: %s", __PRETTY_FUNCTION__, url.c_str());
306 boost::regex urlRegex(R"(^(https?|ftp)://[^\s/$.?#].[^\s]*$)");
308 if (!url.empty() && url != "about:blank" && url != "about:home") {
309 if (boost::regex_match(url, urlRegex))
311 else if (boost::regex_match(std::string("http://") + url, urlRegex) && url.find(".") != std::string::npos)
312 return std::string("http://") + url;
314 std::string searchString("http://www.google.com/search?q=");
316 std::replace(searchString.begin(), searchString.end(), ' ', '+');
317 BROWSER_LOGD("[%s:%d] Search string: %s", __PRETTY_FUNCTION__, __LINE__, searchString.c_str());
326 void URIEntry::editingCanceled()
328 BROWSER_LOGD("[%s:%d] oryinal URL: %s ", __PRETTY_FUNCTION__, __LINE__, m_oryginalEntryText.c_str());
329 if (!m_oryginalEntryText.empty()) {
330 elm_entry_entry_set(m_entry, elm_entry_utf8_to_markup(m_oryginalEntryText.c_str()));
331 m_oryginalEntryText = "";
333 elm_entry_input_panel_hide(m_entry);
337 void URIEntry::AddAction(sharedAction action)
339 m_actions.push_back(action);
342 std::list<sharedAction> URIEntry::actions() const
347 void URIEntry::clearFocus()
349 elm_object_focus_set(m_entry, EINA_FALSE);
352 void URIEntry::setFocus()
354 elm_object_focus_set(m_entryBtn, EINA_TRUE);
357 bool URIEntry::hasFocus() const
359 return elm_object_focus_get(m_entry) == EINA_TRUE ? true : false;
362 void URIEntry::focusedBtn(void* data, Evas_Object* /*obj*/, void* /*event_info*/)
364 URIEntry* self = static_cast<URIEntry*>(data);
365 elm_object_signal_emit(self->m_entry_layout, "mouse,in", "over");
368 void URIEntry::unfocusedBtn(void* data, Evas_Object* /*obj*/, void* /*event_info*/)
370 URIEntry* self = static_cast<URIEntry*>(data);
371 elm_object_signal_emit(self->m_entry_layout, "mouse,out", "over");
372 //elm_entry_entry_set(self->m_entry, elm_entry_utf8_to_markup(self->m_pageTitle.c_str()));
375 void URIEntry::setDisabled(bool disabled)
380 elm_object_disabled_set(getContent(), disabled ? EINA_TRUE : EINA_FALSE);