--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * TabEnum.h
+ *
+ * Created on: Sep 8, 2016
+ * Author: m.kawonczyk@samsung.com
+ */
+
+#ifndef TABENUMS_H
+#define TABENUMS_H
+
+#include <string>
+
+#include "app_i18n.h"
+
+#define ADD_TRAN(x,y) static std::string x = _(y);
+
+namespace tizen_browser
+{
+namespace base_ui
+{
+namespace Translations {
+ //TODO: Missing translation "IDS_BR_BODY_YOUR_PASSWORD_MUST_CONTAIN_AT_LEAST_PD_CHARACTERS_INCLUDING_AT_LEAST_1_LETTER"
+ ADD_TRAN(CreatePassword,"Your password must contain at least %d characters, including at least 1 letter.")
+ //TODO: Missing translation
+ ADD_TRAN(ConfirmCreatePassword, "Enter the password again to confirm it.")
+ //TODO: Missing translation "IDS_BR_BODY_ENTER_YOUR_CURRENT_SECRET_MODE_PASSWORD"
+ ADD_TRAN(ConfirmPassword, "Enter your Secret mode password.")
+ //TODO: Missing translation "IDS_BR_BODY_AN_INCORRECT_PASSWORD_HAS_BEEN_ENTERED_TRY_AGAIN"
+ ADD_TRAN(IncorrectPassword, "An incorrect password has been entered. Try again.")
+ //TODO: Missing translation "IDS_BR_OPT_SHOW_PASSWORD_ABB2"
+ ADD_TRAN(ShowPassword, "Show Password")
+ //TODO: Missing translation "IDS_BR_BUTTON_USE_PASSWORD_ABB"
+ ADD_TRAN(UsePassword, "Use Password")
+ //TODO: Missing translation "IDS_BR_TMBODY_CHANGE_PASSWORD"
+ ADD_TRAN(ChangePassword, "Change Password")
+};
+
+enum class PasswordAction {
+ UsePassword,
+ ChangePassword,
+ CreatePasswordFirstTime,
+ ConfirmPasswordEnterSecret
+};
+
+enum class PasswordState {
+ ConfirmPassword,
+ IncorrectPassword,
+ CreatePassword,
+ ConfirmCreatePassword,
+ SecretModeData
+};
+
+}
+}
+
+#endif // TABENUMS_H
--- /dev/null
+collections {
+ base_scale: 2.6;
+
+ group {
+ name: "elm/genlist/item/entry_custom_layout/default";
+ styles {
+ style { name: "text_style";
+ base: "font=Tizen:style=Regular font_size=42 color=#000000 color_class=T0231 text_class=T0231 wrap=word";
+ tag: "br" "\n";
+ tag: "ps" "ps";
+ tag: "tab" "\t";
+ tag: "b" "+ font_weight=Bold";
+ }
+ }
+ data.item: "texts" "elm.text";
+ data.item: "banded_bg_area" "elm.swallow.bg";
+ data.item: "contents" "elm.swallow.content";
+ parts {
+ swallow { "elm.swallow.bg"; scale;
+ desc { "default";
+ }
+ }
+ part { name: "bg";
+ type: RECT;
+ description { state: "default" 0.0;
+ color: 0 0 0 0;
+ }
+ description { state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 10;
+ }
+ description { state: "disabled" 0.0;
+ color: 0 0 0 0;
+ }
+ }
+ part { name: "base";
+ type: SPACER;
+ scale: 1;
+ description { state: "default" 0.0;
+ }
+ }
+ part { name: "left_padding";
+ type: SPACER;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 32 0;
+ align: 0.0 0.0;
+ rel1 { to: "base"; relative: 0.0 0.0; }
+ rel2 { to: "base"; relative: 0.0 1.0; }
+ }
+ }
+ part { name: "right_padding";
+ type: SPACER;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 32 0;
+ align: 1.0 0.0;
+ rel1 { to: "base"; relative: 1.0 0.0; }
+ rel2 { to: "base"; relative: 1.0 1.0; }
+ }
+ }
+ part { name: "top_padding";
+ type: SPACER;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 0 24;
+ align: 0.0 0.0;
+ rel1 { to_x: "left_padding"; to_y: "base"; relative: 1.0 0.0; }
+ rel2 { to_x: "right_padding"; to_y: "base"; relative: 0.0 0.0; }
+ }
+ }
+ part { name: "elm.text";
+ type: TEXTBLOCK;
+ scale: 1;
+ multiline: 1;
+ mouse_events: 0;
+ description { state: "default" 0.0;
+ min: 0 54;
+ align: 0.0 0.0;
+ fixed: 0 0;
+ rel1 { to: "top_padding"; relative: 0.0 1.0; }
+ rel2 { to: "top_padding"; relative: 1.0 1.0; }
+ text.style: "text_style";
+ text.min: 0 1;
+ }
+ }
+ part { name: "text_content_padding";
+ type: SPACER;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 0 24;
+ align: 0.0 0.0;
+ rel1 { to: "elm.text"; relative: 0.0 1.0; }
+ rel2 { to_x: "right_padding"; to_y: "base"; relative: 0.0 0.0; }
+ }
+ }
+ part { name: "elm.swallow.content";
+ type: SWALLOW;
+ scale: 1;
+ description { state: "default" 0.0;
+ align: 0.5 0.0;
+ rel1 { to: "text_content_padding"; relative: 0.0 1.0; }
+ rel2 { to: "bottom_padding"; relative: 1.0 0.0; }
+ }
+ }
+ part { name: "bottom_padding";
+ type: SPACER;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 0 24;
+ align: 0.5 1.0;
+ rel1 { to: "base"; relative: 0.0 1.0; }
+ rel2 { to: "base"; relative: 1.0 1.0; }
+ }
+ }
+ rect { "elm.bottomline"; scale;
+ description { "default";
+ min: 0 2;
+ max: -1 2;
+ align: 0.5 0.0;
+ fixed: 0 1;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 0.0;
+ color: 204 204 204 255;
+ }
+ desc { "hidden"; inherit: "default";
+ visible: 0;
+ }
+ }
+ }
+ programs {
+ program {
+ signal: "elm,state,elm.swallow.bg,visible";
+ source: "elm";
+ action: STATE_SET "hidden" 0.0;
+ target: "elm.bottomline";
+ }
+ program { name: "default";
+ signal: "elm,state,default";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "bg";
+ target: "elm.bottomline";
+ }
+ program { name: "pressed";
+ signal: "elm,state,selected";
+ source: "elm";
+ action: STATE_SET "pressed" 0.0;
+ target: "bg";
+ }
+ program { name: "unpressed";
+ signal: "elm,state,unselected";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "bg";
+ }
+ program { name: "enabled";
+ signal: "elm,state,enabled";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "bg";
+ }
+ program { name: "disabled";
+ signal: "elm,state,disabled";
+ source: "elm";
+ action: STATE_SET "disabled" 0.0;
+ target: "bg";
+ }
+ }
+ }
+}
_genlist_folder_content_get);
m_add_to_qa_item_class = createGenlistItemClass("type1", _genlist_add_to_qa_text_get,
_genlist_add_to_qa_content_get);
- elm_genlist_item_class_new();
}
Elm_Genlist_Item_Class* BookmarkFlowUI::createGenlistItemClass(
#include "../../../core/Tools/edc/FolderImage.edc"
-
-collections {
- base_scale: 2.6;
-
- group {
- name: "elm/genlist/item/entry_custom_layout/default";
- styles {
- style { name: "text_style";
- base: "font=Tizen:style=Regular font_size=42 color=#000000 color_class=T0231 text_class=T0231 ellipsis=1.0";
- tag: "br" "\n";
- tag: "ps" "ps";
- tag: "tab" "\t";
- tag: "b" "+ font_weight=Bold";
- }
- }
- data.item: "texts" "elm.text";
- data.item: "banded_bg_area" "elm.swallow.bg";
- data.item: "contents" "elm.swallow.content";
- parts {
- swallow { "elm.swallow.bg"; scale;
- desc { "default";
- }
- }
- part { name: "bg";
- type: RECT;
- description { state: "default" 0.0;
- color: 0 0 0 0;
- }
- description { state: "pressed" 0.0;
- inherit: "default" 0.0;
- color: 0 0 0 10;
- }
- description { state: "disabled" 0.0;
- color: 0 0 0 0;
- }
- }
- part { name: "base";
- type: SPACER;
- scale: 1;
- description { state: "default" 0.0;
- }
- }
- part { name: "left_padding";
- type: SPACER;
- scale: 1;
- description { state: "default" 0.0;
- min: 32 0;
- align: 0.0 0.0;
- rel1 { to: "base"; relative: 0.0 0.0; }
- rel2 { to: "base"; relative: 0.0 1.0; }
- }
- }
- part { name: "right_padding";
- type: SPACER;
- scale: 1;
- description { state: "default" 0.0;
- min: 32 0;
- align: 1.0 0.0;
- rel1 { to: "base"; relative: 1.0 0.0; }
- rel2 { to: "base"; relative: 1.0 1.0; }
- }
- }
- part { name: "top_padding";
- type: SPACER;
- scale: 1;
- description { state: "default" 0.0;
- min: 0 24;
- align: 0.0 0.0;
- rel1 { to_x: "left_padding"; to_y: "base"; relative: 1.0 0.0; }
- rel2 { to_x: "right_padding"; to_y: "base"; relative: 0.0 0.0; }
- }
- }
- part { name: "elm.text";
- type: TEXTBLOCK;
- scale: 1;
- mouse_events: 0;
- description { state: "default" 0.0;
- min: 0 54;
- align: 0.0 0.0;
- rel1 { to: "top_padding"; relative: 0.0 1.0; }
- rel2 { to: "top_padding"; relative: 1.0 1.0; }
- text.style: "text_style";
- text.min: 0 1;
- }
- }
- part { name: "text_content_padding";
- type: SPACER;
- scale: 1;
- description { state: "default" 0.0;
- min: 0 78;
- align: 0.0 0.0;
- rel1 { to: "base"; relative: 0.0 0.0; }
- rel2 { to_x: "right_padding"; to_y: "base"; relative: 0.0 0.0; }
- }
- }
- part { name: "elm.swallow.content";
- type: SWALLOW;
- scale: 1;
- description { state: "default" 0.0;
- align: 0.5 0.0;
- rel1 { to: "text_content_padding"; relative: 0.0 1.0; }
- rel2 { to: "bottom_padding"; relative: 1.0 0.0; }
- }
- }
- part { name: "bottom_padding";
- type: SPACER;
- scale: 1;
- description { state: "default" 0.0;
- min: 0 24;
- align: 0.5 1.0;
- rel1 { to: "base"; relative: 0.0 1.0; }
- rel2 { to: "base"; relative: 1.0 1.0; }
- }
- }
- rect { "elm.bottomline"; scale;
- description { "default";
- min: 0 2;
- max: -1 2;
- align: 0.5 0.0;
- fixed: 0 1;
- rel1.relative: 0.0 0.0;
- rel2.relative: 1.0 0.0;
- color: 204 204 204 255;
- }
- desc { "hidden"; inherit: "default";
- visible: 0;
- }
- }
- }
- programs {
- program {
- signal: "elm,state,elm.swallow.bg,visible";
- source: "elm";
- action: STATE_SET "hidden" 0.0;
- target: "elm.bottomline";
- }
- program { name: "default";
- signal: "elm,state,default";
- source: "elm";
- action: STATE_SET "default" 0.0;
- target: "bg";
- target: "elm.bottomline";
- }
- program { name: "pressed";
- signal: "elm,state,selected";
- source: "elm";
- action: STATE_SET "pressed" 0.0;
- target: "bg";
- }
- program { name: "unpressed";
- signal: "elm,state,unselected";
- source: "elm";
- action: STATE_SET "default" 0.0;
- target: "bg";
- }
- program { name: "enabled";
- signal: "elm,state,enabled";
- source: "elm";
- action: STATE_SET "default" 0.0;
- target: "bg";
- }
- program { name: "disabled";
- signal: "elm,state,disabled";
- source: "elm";
- action: STATE_SET "disabled" 0.0;
- target: "bg";
- }
- }
- }
-}
+#include "../../../core/Tools/edc/EntryCustomLayout.edc"
m_tabUI->closeTabsClicked.connect(boost::bind(&SimpleUI::closeTabsClicked, this,_1));
m_tabUI->getWindow.connect(boost::bind(&SimpleUI::getMainWindow, this));
m_tabUI->isLandscape.connect(boost::bind(&SimpleUI::isLandscape, this));
- m_tabUI->changeEngineState.connect(boost::bind(&basic_webengine::AbstractWebEngine::changeState, m_webEngine.get()));
m_tabUI->changeEngineState.connect(boost::bind(&SimpleUI::changeEngineState, this));
m_tabUI->refetchTabUIData.connect(boost::bind(&SimpleUI::refetchTabUIData, this));
- m_tabUI->checkIfParamExistsInDB.connect(boost::bind(&storage::SettingsStorage::isDBParamPresent, &m_storageService->getSettingsStorage(), _1));
- m_tabUI->setDBBoolParamValue.connect(boost::bind(&storage::SettingsStorage::setSettingsBool, &m_storageService->getSettingsStorage(), _1, _2));
- m_tabUI->setDBStringParamValue.connect(boost::bind(&storage::SettingsStorage::setSettingsString, &m_storageService->getSettingsStorage(), _1, _2));
- m_tabUI->getDBBoolParamValue.connect(boost::bind(&storage::SettingsStorage::getSettingsBool, &m_storageService->getSettingsStorage(), _1, false));
- m_tabUI->getDBStringParamValue.connect(boost::bind(&storage::SettingsStorage::getSettingsText, &m_storageService->getSettingsStorage(), _1, ""));
+ m_tabUI->checkIfParamExistsInDB.connect(boost::bind(&storage::SettingsStorage::isDBParamPresent,
+ &m_storageService->getSettingsStorage(), _1));
+ m_tabUI->setDBBoolParamValue.connect(boost::bind(&storage::SettingsStorage::setSettingsBool,
+ &m_storageService->getSettingsStorage(), _1, _2));
+ m_tabUI->setDBStringParamValue.connect(boost::bind(&storage::SettingsStorage::setSettingsString,
+ &m_storageService->getSettingsStorage(), _1, _2));
+ m_tabUI->getDBBoolParamValue.connect(boost::bind(&storage::SettingsStorage::getSettingsBool,
+ &m_storageService->getSettingsStorage(), _1, false));
+ m_tabUI->getDBStringParamValue.connect(boost::bind(&storage::SettingsStorage::getSettingsText,
+ &m_storageService->getSettingsStorage(), _1, ""));
m_tabUI->showPasswordUI.connect(boost::bind(&SimpleUI::showPasswordUI, this));
m_tabUI->getPasswordUI().closeUI.connect(boost::bind(&SimpleUI::closeTopView, this));
- m_tabUI->getPasswordUI().setDBStringParamValue.connect(boost::bind(&storage::SettingsStorage::setSettingsString, &m_storageService->getSettingsStorage(), _1, _2));
+ m_tabUI->getPasswordUI().setDBStringParamValue.connect(boost::bind(&storage::SettingsStorage::setSettingsString,
+ &m_storageService->getSettingsStorage(), _1, _2));
+ m_tabUI->getPasswordUI().setDBBoolParamValue.connect(boost::bind(&storage::SettingsStorage::setSettingsBool,
+ &m_storageService->getSettingsStorage(), _1, _2));
+ m_tabUI->getPasswordUI().getDBStringParamValue.connect(boost::bind(&storage::SettingsStorage::getSettingsText,
+ &m_storageService->getSettingsStorage(), _1, ""));
+ m_tabUI->getPasswordUI().getDBBoolParamValue.connect(boost::bind(&storage::SettingsStorage::getSettingsBool,
+ &m_storageService->getSettingsStorage(), _1, false));
+ m_tabUI->getPasswordUI().changeEngineState.connect(boost::bind(&SimpleUI::changeEngineState, this));
M_ASSERT(m_historyUI.get());
m_historyUI->clearHistoryClicked.connect(boost::bind(&SimpleUI::onClearHistoryAllClicked, this));
if (!m_webPageUI->stateEquals(WPUState::QUICK_ACCESS) && m_webEngine->tabsCount() > 0 && m_webEngine->isLoading())
onGenerateThumb(m_webEngine->currentTabId());
- std::vector<basic_webengine::TabContentPtr> tabsContents =
- m_webEngine->getTabContents();
- m_tabService->fillThumbs(tabsContents);
- m_tabUI->addTabItems(tabsContents);
}
void SimpleUI::closeTabUI()
std::vector<basic_webengine::TabContentPtr> tabsContents =
m_webEngine->getTabContents();
m_tabService->fillThumbs(tabsContents);
- m_tabUI->addTabItems(tabsContents);
+ m_tabUI->addTabItems(tabsContents, m_webEngine->isSecretMode());
}
void SimpleUI::newTabClicked()
void SimpleUI::changeEngineState()
{
+ m_webEngine->changeState();
m_webEngine->disconnectCurrentWebViewSignals();
m_webPageUI->switchViewToQuickAccess(m_quickAccess->getContent());
updateView();
#include "BrowserAssert.h"
#include "PasswordUI.h"
#include "BrowserLogger.h"
+#include <boost/format.hpp>
+#include "app_i18n.h"
+#include "EflTools.h"
namespace tizen_browser{
namespace base_ui{
const std::string PasswordUI::PASSWORD_FIELD = "secret_password";
+const std::string PasswordUI::DECISION_MADE = "password_decision";
+const int PasswordUI::PASSWORD_MINIMUM_CHARACTERS = 6;
PasswordUI::PasswordUI()
: m_parent(nullptr)
- , m_content(nullptr)
+ , m_genlist(nullptr)
, m_entry(nullptr)
, m_checkbox(nullptr)
+ , m_state(PasswordState::CreatePassword)
{
m_edjFilePath = EDJE_DIR;
m_edjFilePath.append("TabUI/PasswordUI.edj");
+ createGenlistItemClasses();
}
PasswordUI::~PasswordUI()
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
M_ASSERT(m_naviframe->getLayout());
m_naviframe->show();
+ changeState(m_state);
}
void PasswordUI::hideUI()
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
M_ASSERT(m_naviframe->getLayout());
m_naviframe->hide();
+
+ elm_genlist_clear(m_genlist);
+ m_genlistItemData.clear();
}
void PasswordUI::init(Evas_Object* parent)
return m_naviframe->getLayout();
}
+void PasswordUI::createGenlistItemClasses()
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ m_password_item_class = createGenlistItemClass("entry_custom_layout", _genlist_item_text_get,
+ _genlist_password_content_get);
+ m_checkbox_item_class = createGenlistItemClass("type1", _genlist_item_text_get,
+ _genlist_checkbox_content_get);
+ m_check_on_of_item_class = createGenlistItemClass("type1", _genlist_item_text_get,
+ _genlist_check_on_off_content_get);
+ m_text_item_class = createGenlistItemClass("type1", _genlist_item_text_get);
+}
+
+Elm_Genlist_Item_Class* PasswordUI::createGenlistItemClass(
+ const char* style, Elm_Gen_Item_Text_Get_Cb text_cb, Elm_Gen_Item_Content_Get_Cb content_cb)
+{
+ auto ic = elm_genlist_item_class_new();
+ ic->item_style = style;
+ ic->func.text_get = text_cb;
+ ic->func.content_get = content_cb;
+ ic->func.state_get = nullptr;
+ ic->func.del = nullptr;
+ ic->decorate_all_item_style = "edit_default";
+ return ic;
+}
+
+char* PasswordUI::_genlist_item_text_get(void *data, Evas_Object *, const char *part)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data && part) {
+ if (!strcmp(part, "elm.text")) {
+ PasswordUIData *passwordData = static_cast<PasswordUIData*>(data);
+ return strdup(passwordData->text.c_str());
+ }
+ } else {
+ BROWSER_LOGE("[%s:%d] Data or part is null", __PRETTY_FUNCTION__, __LINE__);
+ }
+ return nullptr;
+}
+
+Evas_Object* PasswordUI::_genlist_password_content_get(void *data, Evas_Object *obj, const char *part)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data && part) {
+ PasswordUIData *passwordData = static_cast<PasswordUIData*>(data);
+ if (!strcmp(part, "elm.swallow.content")) {
+ Evas_Object* entry_layout = elm_layout_add(obj);
+ elm_layout_theme_set(entry_layout, "layout", "editfield", "multiline");
+ tools::EflTools::setExpandHints(entry_layout);
+
+ passwordData->passwordUI->m_entry = elm_entry_add(entry_layout);
+ elm_entry_single_line_set(passwordData->passwordUI->m_entry, EINA_TRUE);
+ elm_entry_scrollable_set(passwordData->passwordUI->m_entry, EINA_TRUE);
+ tools::EflTools::setExpandHints(passwordData->passwordUI->m_entry);
+ elm_entry_entry_set(passwordData->passwordUI->m_entry, elm_entry_utf8_to_markup(""));
+ elm_entry_password_set(passwordData->passwordUI->m_entry, EINA_TRUE);
+ elm_entry_input_panel_return_key_type_set(passwordData->passwordUI->m_entry,
+ ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE);
+
+ evas_object_smart_callback_add(passwordData->passwordUI->m_entry, "focused",
+ _entry_focused, entry_layout);
+ evas_object_smart_callback_add(passwordData->passwordUI->m_entry, "unfocused",
+ _entry_unfocused, entry_layout);
+ evas_object_smart_callback_add(passwordData->passwordUI->m_entry, "activated",
+ _entry_submited, passwordData->passwordUI);
+
+ elm_object_part_content_set(entry_layout, "elm.swallow.content", passwordData->passwordUI->m_entry);
+
+ return entry_layout;
+ }
+ } else {
+ BROWSER_LOGE("[%s:%d] Data or part is null", __PRETTY_FUNCTION__, __LINE__);
+ }
+ return nullptr;
+}
+
+Evas_Object* PasswordUI::_genlist_checkbox_content_get(void *data, Evas_Object *obj, const char *part)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data && part) {
+ PasswordUIData *passwordData = static_cast<PasswordUIData*>(data);
+ if (!strcmp(part, "elm.swallow.end")) {
+ passwordData->passwordUI->m_checkbox = elm_check_add(obj);
+ evas_object_propagate_events_set(passwordData->passwordUI->m_checkbox, EINA_FALSE);
+ elm_check_state_set(passwordData->passwordUI->m_checkbox, EINA_FALSE);
+ evas_object_smart_callback_add(passwordData->passwordUI->m_checkbox, "changed",
+ _show_password_state_changed, passwordData->passwordUI);
+ evas_object_show(passwordData->passwordUI->m_checkbox);
+ return passwordData->passwordUI->m_checkbox;
+ }
+ } else {
+ BROWSER_LOGE("[%s:%d] Data or part is null", __PRETTY_FUNCTION__, __LINE__);
+ }
+ return nullptr;
+}
+
+Evas_Object* PasswordUI::_genlist_check_on_off_content_get(void *data, Evas_Object *obj, const char *part)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (part) {
+ PasswordUIData *passwordData = static_cast<PasswordUIData*>(data);
+ if (!strcmp(part, "elm.swallow.end")) {
+ auto checkbox = elm_check_add(obj);
+ elm_object_style_set(checkbox, "on&off");
+ elm_check_state_set(checkbox,
+ passwordData->passwordUI->getDBPassword().empty() ? EINA_FALSE : EINA_TRUE);
+ evas_object_propagate_events_set(checkbox, EINA_TRUE);
+ return checkbox;
+ }
+ } else {
+ BROWSER_LOGE("[%s:%d] Part is null", __PRETTY_FUNCTION__, __LINE__);
+ }
+ return nullptr;
+}
+
void PasswordUI::createLayout()
{
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
M_ASSERT(m_parent);
- elm_theme_extension_add(nullptr, m_edjFilePath.c_str());
+ elm_theme_extension_add(nullptr, m_edjFilePath.c_str());
m_naviframe = std::make_unique<NaviframeWrapper>(m_parent);
- m_content = elm_layout_add(m_naviframe->getLayout());
- evas_object_size_hint_weight_set(m_content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(m_content, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(m_content);
- elm_layout_file_set(m_content, m_edjFilePath.c_str(), "main_layout");
-
- elm_layout_text_set(m_content, "instruction", "Your password must contain at "
- "least 6 characters, including at least one letter.");
-
- m_entry = elm_entry_add(m_content);
- elm_entry_password_set(m_entry, EINA_TRUE);
- evas_object_show(m_entry);
- elm_layout_content_set(m_content, "password_field", m_entry);
-
- m_checkbox = elm_check_add(m_content);
- elm_check_state_set(m_checkbox, EINA_FALSE);
- evas_object_smart_callback_add(m_checkbox, "changed", _show_password_state_changed, this);
- evas_object_show(m_checkbox);
- elm_layout_content_set(m_content, "show_password", m_checkbox);
- elm_layout_text_set(m_content, "chb_label", "Show password");
-
- m_naviframe->setContent(m_content);
- m_naviframe->setTitle("Create password");
+ m_genlist = elm_genlist_add(m_naviframe->getLayout());
+ elm_scroller_policy_set(m_genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
+ elm_genlist_multi_select_set(m_genlist, EINA_FALSE);
+ elm_genlist_select_mode_set(m_genlist, ELM_OBJECT_SELECT_MODE_ALWAYS);
+ elm_genlist_mode_set(m_genlist, ELM_LIST_COMPRESS);
+ tools::EflTools::setExpandHints(m_genlist);
+
+ m_naviframe->setContent(m_genlist);
+ evas_object_show(m_genlist);
+
m_naviframe->addPrevButton(_close_clicked, this);
m_naviframe->setPrevButtonVisible(true);
+}
+void PasswordUI::changeState(PasswordState state)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+
+ elm_genlist_clear(m_genlist);
+ m_state = state;
+
+ BROWSER_LOGD("___________ %d", m_state);
+ if (m_state != PasswordState::SecretModeData) {
+ //Add password item
+ auto passwordData = std::make_shared<PasswordUIData>();
+ m_genlistItemData.push_back(passwordData);
+ std::string text = "";
- m_naviframe->setVisibleBottomBar(true);
- m_naviframe->addButtonToBottomBar("Cancel", _left_button_clicked, this);
- m_naviframe->setEnableButtonInBottomBar(0, true);
- m_naviframe->addButtonToBottomBar("Save", _right_button_clicked, this);
- m_naviframe->setEnableButtonInBottomBar(1, true);
+ switch (m_state) {
+ case PasswordState::ConfirmPassword:
+ text = _(Translations::ConfirmPassword.c_str());
+ m_naviframe->setTitle("Confirm password");
+ break;
+ case PasswordState::IncorrectPassword:
+ text = _(Translations::IncorrectPassword.c_str());
+ break;
+ case PasswordState::CreatePassword:
+ text = (boost::format(_(Translations::CreatePassword.c_str()))
+ % PASSWORD_MINIMUM_CHARACTERS).str();
+ m_naviframe->setTitle("Create password");
+ break;
+ case PasswordState::ConfirmCreatePassword:
+ text = _(Translations::ConfirmCreatePassword.c_str());
+ break;
+ default:
+ break;
+ }
+ BROWSER_LOGD("___________ %s", text.c_str());
+ passwordData->text = text;
+ passwordData->passwordUI = this;
+ m_password_item = elm_genlist_item_append(m_genlist, m_password_item_class, passwordData.get(),
+ nullptr, ELM_GENLIST_ITEM_NONE, nullptr, passwordData.get());
+ //Add ShowPassword checkbox
+ auto checkboxData = std::make_shared<PasswordUIData>();
+ m_genlistItemData.push_back(checkboxData);
+ checkboxData->text = _(Translations::ShowPassword.c_str());
+ checkboxData->passwordUI = this;
+ elm_genlist_item_append(m_genlist, m_checkbox_item_class, checkboxData.get(), nullptr,
+ ELM_GENLIST_ITEM_NONE, _show_password_clicked, checkboxData.get());
+ } else {
+ m_naviframe->setTitle("Secret mode security");
+ //Add UsePassword check_on_off
+ auto checkOnOffData = std::make_shared<PasswordUIData>();
+ m_genlistItemData.push_back(checkOnOffData);
+ checkOnOffData->text = _(Translations::UsePassword.c_str());
+ checkOnOffData->passwordUI = this;
+ elm_genlist_item_append(m_genlist, m_check_on_of_item_class, checkOnOffData.get(), nullptr,
+ ELM_GENLIST_ITEM_NONE, _use_password_clicked, checkOnOffData.get());
+
+ //Add ChangePassword
+ if (!getDBPassword().empty()) {
+ auto changeData = std::make_shared<PasswordUIData>();
+ m_genlistItemData.push_back(changeData);
+ changeData->text = _(Translations::ChangePassword.c_str());
+ changeData->passwordUI = this;
+ elm_genlist_item_append(m_genlist, m_text_item_class, changeData.get(), nullptr,
+ ELM_GENLIST_ITEM_NONE, _change_password_clicked, changeData.get());
+ }
+ }
+}
+std::string PasswordUI::getDBPassword()
+{
+ auto password = getDBStringParamValue(PASSWORD_FIELD);
+ if (password)
+ return *password;
+ else
+ BROWSER_LOGW("[%s:%d] Wrong boost signal value!", __PRETTY_FUNCTION__, __LINE__);
+ return std::string();
+}
+
+bool PasswordUI::checkIfStringContainsLetter(const std::string& s)
+{
+ return std::any_of(std::begin(s), std::end(s), ::isalpha);
}
void PasswordUI::_close_clicked(void* data, Evas_Object*, void*)
self->closeUI();
}
-void PasswordUI::_right_button_clicked(void* data, Evas_Object*, void*)
+void PasswordUI::_entry_focused(void * data, Evas_Object *, void *)
{
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
- auto self = static_cast<PasswordUI*>(data);
- std::string hash = std::to_string(
- static_cast<int>(
- std::hash<std::string>()(std::string(elm_object_text_get(self->m_entry)))
- )
- );
- self->setDBStringParamValue(PASSWORD_FIELD, hash);
+ if (data)
+ elm_object_signal_emit((Evas_Object*)data, "elm,state,focused", "");
+ else
+ BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
+}
- // TODO: set PASSWORD_DECISION_MADE flag to true
+void PasswordUI::_entry_unfocused(void * data, Evas_Object *, void *)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data)
+ elm_object_signal_emit((Evas_Object*)data, "elm,state,unfocused", "");
+ else
+ BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
}
-void PasswordUI::_left_button_clicked(void* data, Evas_Object*, void*)
+void PasswordUI::_entry_submited(void * data, Evas_Object *, void *)
{
- auto self = static_cast<PasswordUI*>(data);
- elm_entry_entry_set(self->m_entry, "");
- self->closeUI();
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data) {
+ auto self = static_cast<PasswordUI*>(data);
+ std::string hash = std::to_string(
+ std::hash<std::string>()(std::string(elm_object_text_get(self->m_entry)))
+ );
+ switch (self->m_state) {
+ case PasswordState::ConfirmPassword:
+ case PasswordState::IncorrectPassword: {
+ if (self->getDBPassword() == hash)
+ switch (self->m_action) {
+ case PasswordAction::ChangePassword:
+ self->changeState(PasswordState::CreatePassword);
+ break;
+ case PasswordAction::UsePassword:
+ self->setDBStringParamValue(PASSWORD_FIELD, "");
+ self->changeState(PasswordState::SecretModeData);
+ break;
+ case PasswordAction::ConfirmPasswordEnterSecret:
+ self->changeEngineState();
+ self->closeUI();
+ default:
+ BROWSER_LOGW("Action state is not supported in Password workflow");
+ break;
+ }
+ else
+ self->changeState(PasswordState::IncorrectPassword);
+ break; }
+ case PasswordState::CreatePassword: {
+ std::string s = std::string(elm_object_text_get(self->m_entry));
+ if (s.length() < PASSWORD_MINIMUM_CHARACTERS ||
+ !checkIfStringContainsLetter(s)) {
+ elm_object_text_set(self->m_entry, "");
+ } else {
+ self->m_not_confirmed_hash = hash;
+ self->changeState(PasswordState::ConfirmCreatePassword);
+ }
+ break; }
+ case PasswordState::ConfirmCreatePassword:
+ if (hash == self->m_not_confirmed_hash) {
+ self->setDBStringParamValue(PASSWORD_FIELD, hash);
+ if (self->m_action == PasswordAction::CreatePasswordFirstTime) {
+ self->setDBBoolParamValue(DECISION_MADE, true);
+ self->changeEngineState();
+ self->closeUI();
+ } else {
+ self->changeState(PasswordState::SecretModeData);
+ }
+ } else {
+ self->changeState(PasswordState::ConfirmCreatePassword);
+ }
+ break;
+ default:
+ BROWSER_LOGW("Password state is not supported in Password workflow");
+ }
+ } else {
+ BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
+ }
}
void PasswordUI::_show_password_state_changed(void* data, Evas_Object*, void*)
{
- auto self = static_cast<PasswordUI*>(data);
- elm_entry_password_set(self->m_entry, !elm_check_state_get(self->m_checkbox));
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data) {
+ auto self = static_cast<PasswordUI*>(data);
+ elm_entry_password_set(self->m_entry, !elm_check_state_get(self->m_checkbox));
+ } else {
+ BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
+ }
+}
+
+void PasswordUI::_show_password_clicked(void *data, Evas_Object *, void *)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data) {
+ PasswordUI* passwordUI = static_cast<PasswordUI*>(data);
+ elm_check_state_set(passwordUI->m_checkbox,
+ !elm_check_state_get(passwordUI->m_checkbox));
+ elm_entry_password_set(passwordUI->m_entry, !elm_check_state_get(passwordUI->m_checkbox));
+ } else {
+ BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
+ }
+}
+
+void PasswordUI::_use_password_clicked(void *data, Evas_Object *, void *)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data) {
+ PasswordUIData* passwordData = static_cast<PasswordUIData*>(data);
+ passwordData->passwordUI->setAction(PasswordAction::UsePassword);
+ if (passwordData->passwordUI->getDBPassword().empty()) { // start using password
+ passwordData->passwordUI->changeState(PasswordState::CreatePassword);
+ } else { // stop using password
+ passwordData->passwordUI->changeState(PasswordState::ConfirmPassword);
+ }
+ } else {
+ BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
+ }
+}
+
+void PasswordUI::_change_password_clicked(void *data, Evas_Object *, void *)
+{
+ BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ if (data) {
+ PasswordUIData* passwordData = static_cast<PasswordUIData*>(data);
+ passwordData->passwordUI->m_action = PasswordAction::ChangePassword;
+ passwordData->passwordUI->changeState(PasswordState::ConfirmPassword);
+ } else {
+ BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
+ }
}
}
-}
\ No newline at end of file
+}
#include <memory>
#include "AbstractInterfaces/AbstractUIComponent.h"
#include "NaviframeWrapper.h"
+#include "TabEnums.h"
namespace tizen_browser {
namespace base_ui {
Evas_Object* getContent() override;
void showUI() override;
void hideUI() override;
+ void setState(PasswordState state) { m_state = state; }
+ void setAction(PasswordAction action) { m_action = action; }
- void createLayout();
boost::signals2::signal<void (std::string, std::string)> setDBStringParamValue;
+ boost::signals2::signal<std::string (std::string)> getDBStringParamValue;
+ boost::signals2::signal<void (std::string, bool)> setDBBoolParamValue;
+ boost::signals2::signal<bool (std::string)> getDBBoolParamValue;
+ boost::signals2::signal<void ()> changeEngineState;
static const std::string PASSWORD_FIELD;
+ static const std::string DECISION_MADE;
private:
+ struct PasswordUIData {
+ std::string text;
+ PasswordUI* passwordUI;
+ };
+
+ void createGenlistItemClasses();
+ Elm_Genlist_Item_Class* createGenlistItemClass(const char* style,
+ Elm_Gen_Item_Text_Get_Cb text_cb = nullptr, Elm_Gen_Item_Content_Get_Cb content_cb = nullptr);
+ void createLayout();
+ void changeState(PasswordState state);
+ std::string getDBPassword();
+ static bool checkIfStringContainsLetter(const std::string& s);
static void _close_clicked(void *data, Evas_Object *obj, void *event_info);
- static void _right_button_clicked(void * data, Evas_Object * obj, void * event_info);
- static void _left_button_clicked(void * data, Evas_Object * obj, void * event_info);
+ static void _entry_focused(void* data, Evas_Object*, void*);
+ static void _entry_unfocused(void* data, Evas_Object*, void*);
+ static void _entry_submited(void* data, Evas_Object*, void*);
static void _show_password_state_changed(void* data, Evas_Object*, void*);
+ static void _show_password_clicked(void* data, Evas_Object*, void*);
+ static void _use_password_clicked(void* data, Evas_Object*, void*);
+ static void _change_password_clicked(void* data, Evas_Object*, void*);
+ //Genlist items create callbacks
+ static char* _genlist_item_text_get(void *data, Evas_Object *obj, const char *part);
+ static Evas_Object* _genlist_password_content_get(void *data, Evas_Object *obj, const char *part);
+ static Evas_Object* _genlist_checkbox_content_get(void *data, Evas_Object *obj, const char *part);
+ static Evas_Object* _genlist_check_on_off_content_get(void *data, Evas_Object *obj, const char *part);
Evas_Object* m_parent;
- Evas_Object* m_content;
+ std::unique_ptr<NaviframeWrapper> m_naviframe;
+ Evas_Object* m_genlist;
Evas_Object* m_entry;
Evas_Object* m_checkbox;
- std::unique_ptr<NaviframeWrapper> m_naviframe;
+
+ Elm_Object_Item *m_password_item;
+
+ Elm_Genlist_Item_Class *m_password_item_class;
+ Elm_Genlist_Item_Class *m_checkbox_item_class;
+ Elm_Genlist_Item_Class *m_check_on_of_item_class;
+ Elm_Genlist_Item_Class *m_text_item_class;
+
std::string m_edjFilePath;
+ std::string m_not_confirmed_hash;
+
+ static const int PASSWORD_MINIMUM_CHARACTERS;
+
+ PasswordAction m_action;
+ PasswordState m_state;
+ std::vector<std::shared_ptr<PasswordUIData> > m_genlistItemData;
};
}
EXPORT_SERVICE(TabUI, "org.tizen.browser.tabui")
-const std::string TabUI::PASSWORD_DECISION_MADE = "password_decision";
-
TabUI::TabUI()
: m_parent(nullptr)
, m_content(nullptr)
{
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
M_ASSERT(m_naviframe->getLayout());
+ refetchTabUIData();
m_naviframe->show();
orientationChanged();
}
{
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
M_ASSERT(m_naviframe->getLayout());
- if (m_state == State::PASSWORD_DECISION) {
- m_state = State::NORMAL;
- createEmptyLayout();
- setStateButtons();
- updateNoTabsText();
- }
elm_gengrid_clear(m_gengrid);
m_naviframe->hide();
}
BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
M_ASSERT(parent);
m_parent = parent;
- auto paramExists = checkIfParamExistsInDB(PASSWORD_DECISION_MADE);
+ auto paramExists = checkIfParamExistsInDB(PasswordUI::DECISION_MADE);
if (paramExists) {
if (!*paramExists) {
- setDBBoolParamValue(PASSWORD_DECISION_MADE, false);
+ setDBBoolParamValue(PasswordUI::DECISION_MADE, false);
}
} else {
BROWSER_LOGE("[%s:%d] unknow checkIfParamExistsInDB value!", __PRETTY_FUNCTION__, __LINE__);
if (data) {
TabUI* tabUI = static_cast<TabUI*>(data);
_cm_dismissed(nullptr, tabUI->m_ctxpopup, nullptr);
+ tabUI->m_passwordUI.setState(PasswordState::SecretModeData);
+ tabUI->showPasswordUI();
} else {
BROWSER_LOGW("[%s] data = nullptr", __PRETTY_FUNCTION__);
}
self->newTabClicked();
break;
case State::PASSWORD_DECISION:
+ self->m_passwordUI.setState(PasswordState::CreatePassword);
+ self->m_passwordUI.setAction(PasswordAction::CreatePasswordFirstTime);
self->showPasswordUI();
break;
default:
switch (self->m_state) {
case State::NORMAL: {
- auto decisionMade = self->getDBBoolParamValue(PASSWORD_DECISION_MADE);
+ auto decisionMade = self->getDBBoolParamValue(PasswordUI::DECISION_MADE);
if (decisionMade) {
- if(*decisionMade) {
- //TODO check password
+ if (*decisionMade) {
auto password = self->getDBStringParamValue(PasswordUI::PASSWORD_FIELD);
if (password) {
if (password->empty()) { // password is not used
- self->m_state = State::SECRET;
self->changeEngineState();
self->refetchTabUIData();
} else { // check password validity
- //TODO open screen with password confirm
+ self->m_passwordUI.setState(PasswordState::ConfirmPassword);
+ self->m_passwordUI.setAction(PasswordAction::ConfirmPasswordEnterSecret);
+ self->showPasswordUI();
}
} else {
BROWSER_LOGW("[%s] cannot read password from DB", __PRETTY_FUNCTION__);
}
} break;
case State::SECRET: // disable secret
- self->m_state = State::NORMAL;
self->changeEngineState();
self->refetchTabUIData();
break;
case State::PASSWORD_DECISION: // do not use password
- self->m_state = State::SECRET;
self->setDBStringParamValue(PasswordUI::PASSWORD_FIELD, "");
- self->setDBBoolParamValue(PASSWORD_DECISION_MADE, true);
+ self->setDBBoolParamValue(PasswordUI::DECISION_MADE, true);
self->changeEngineState();
self->refetchTabUIData();
break;
BROWSER_LOGW("GengridItem wasn't created successfully");
}
-void TabUI::addTabItems(std::vector<basic_webengine::TabContentPtr>& items)
+void TabUI::addTabItems(std::vector<basic_webengine::TabContentPtr>& items, bool secret)
{
- BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
+ BROWSER_LOGD("[%s:%d] secret: %d", __PRETTY_FUNCTION__, __LINE__, secret);
+ if (secret)
+ m_state = State::SECRET;
+ else
+ m_state = State::NORMAL;
+
+ createEmptyLayout();
+
elm_gengrid_clear(m_gengrid);
for (auto it = items.begin(); it < items.end(); ++it)
addTabItem(*it);
+
+ setStateButtons();
updateNoTabsText();
}
virtual std::string getName();
- void addTabItems(std::vector<basic_webengine::TabContentPtr>& items);
+ void addTabItems(std::vector<basic_webengine::TabContentPtr>& items, bool secret);
virtual void orientationChanged() override;
//AbstractContextMenu interface implementation
const unsigned int GENGRID_ITEM_WIDTH_LANDSCAPE = 636;
const unsigned int GENGRID_ITEM_HEIGHT_LANDSCAPE = 274;
const unsigned int GESTURE_MOMENTUM_MIN = 2000;
- static const std::string PASSWORD_DECISION_MADE;
};
}
}
-
-collections { base_scale: 2.6;
- group {
- name: "main_layout";
-
- styles {
- style { name: "instruction_style";
- base: "font=Tizen:style=Regular font_size=40 align=left color=#FFFFFF wrap=mixed ellipsis=1.0";
- }
- }
-
- parts {
- rect {
- name: "bg";
- scale: 1;
- description {
- align: 0 0;
- color: 255 255 255 255;
- rel1 { relative: 0.0 0.0; }
- rel2 { relative: 1.0 1.0; }
- }
- }
-
- textblock {
- name: "instruction";
- scale: 1;
- description {
- state: "default" 0.0;
- align: 0 0;
- color: 0 0 0 255;
- min: 0 200;
- max: -1 200;
- rel1 { relative: 0.05 0.0; to: "bg"; }
- rel2 { relative: 0.95 1.0; to: "bg"; }
-
- text {
- style: "instruction_style";
- align: 0.0 0.5;
- }
- }
- }
-
- swallow {
- name: "password_field";
- scale: 1;
- description {
- state: "default" 0.0;
- align: 0 0;
- rel1 { relative: 0.0 1.0; to: "instruction"; }
- rel2 { relative: 0.95 1.0; to: "bg"; }
- }
- }
-
- rect {
- name: "line";
- scale : 1;
- description {
- state: "default" 0.0;
- min: 1 1;
- max: -1 1;
- visible: 1;
- align: 0 0;
- color: 0 0 0 255;
- rel1 { relative: 0.0 1.0; to: "password_field"; }
- rel2 { relative: 0.95 1.0; to: "bg";}
- }
- }
-
- swallow {
- name: "show_password";
- scale: 1;
- description {
- state: "default" 0.0;
- align: 0 0;
- min: 100 100;
- max: 100 100;
- rel1 { relative: 0.0 1.0; to: "line"; }
- rel2 { relative: 1.0 1.0; to: "bg"; }
- }
- }
-
- textblock {
- name: "chb_label";
- scale: 1;
- description {
- state: "default" 0.0;
- align: 0 0;
- color: 0 0 0 255;
- min: 100 100;
- max: -1 100;
- rel1 { relative: 1.0 0.0; to: "show_password"; }
- rel2 { relative: 1.0 1.0; to: "bg"; }
-
- text {
- style: "instruction_style";
- align: 0.0 0.5;
- }
- }
- }
- }
- }
-}
\ No newline at end of file
+#include "../../../core/Tools/edc/EntryCustomLayout.edc"