[Tizen] Add AutofillContainer class and autofill implementation
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / autofill-container-impl.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/text-controls/autofill-container-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23 #include <dali/public-api/object/type-registry-helper.h>
24 #include <dali/integration-api/debug.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
28 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
29
30 namespace Dali
31 {
32
33 namespace Toolkit
34 {
35
36 namespace Internal
37 {
38
39 namespace
40 {
41
42 #if defined ( DEBUG_ENABLED )
43   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_AUTOFILL_CONTAINER");
44 #endif
45
46 // Type registration
47 BaseHandle Create()
48 {
49   return Toolkit::AutofillContainer::New( "" );
50 }
51
52 // Setup properties, signals and actions using the type-registry.
53 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::AutofillContainer, Dali::BaseHandle, Create );
54
55 DALI_SIGNAL_REGISTRATION( Toolkit, AutofillContainer, "serviceShown",   SIGNAL_SERVICE_SHOWN )
56 DALI_SIGNAL_REGISTRATION( Toolkit, AutofillContainer, "listShown",      SIGNAL_LIST_SHOWN )
57
58 DALI_TYPE_REGISTRATION_END()
59
60 } // namespace
61
62 Toolkit::AutofillContainer AutofillContainer::New( const std::string& name )
63 {
64   // Create the implementation, temporarily owned by this handle on stack
65   Internal::AutofillContainer* impl = new AutofillContainer();
66
67   // Pass ownership to CustomActor handle
68   Toolkit::AutofillContainer handle( impl );
69   impl->Initialize( name );
70
71   return handle;
72 }
73
74 void AutofillContainer::Initialize( const std::string& name )
75 {
76   mAutofillManager = Dali::AutofillManager::Get();
77   mAutofillGroup = mAutofillManager.CreateAutofillGroup( name );
78
79   // If the authentication is needed, AuthenticationReceivedSignal would be emitted.
80   mAutofillManager.AuthenticationReceivedSignal().Connect( mSlotDelegate, &AutofillContainer::OnAutofillAuthReceived );
81
82   // If the data to be filled is present, FillResponseReceivedSignal would be emitted.
83   mAutofillManager.FillResponseReceivedSignal().Connect( mSlotDelegate, &AutofillContainer::OnDataFillReceived );
84
85   // If the values to be filled are multiple, ListEventSignal would be emitted.
86   mAutofillManager.ListEventSignal().Connect( mSlotDelegate, &AutofillContainer::OnListReceived );
87 }
88
89 void AutofillContainer::AddAutofillItem( Dali::Toolkit::Control control, Dali::Property::Index propertyIndex, const std::string& id, const std::string& label, Dali::AutofillItem::Hint hint, bool isSensitive )
90 {
91   if( control )
92   {
93     Dali::AutofillItem item = mAutofillManager.CreateAutofillItem( id, label, static_cast<Dali::AutofillItem::Hint>(hint), isSensitive );
94
95     Internal::Control& controlImpl = GetImplementation( control );
96     Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
97     controlDataImpl.SetAutofillContainer( this );
98     controlDataImpl.SetAutofillEnabled( true );
99     controlDataImpl.SetAutofillItemHandle( item ); // TODO : This instance would be here as... std::map or pair
100
101     mAutofillGroup.AddAutofillItem( item );
102
103     mPropertyIndex = propertyIndex;
104
105     // TODO : Remove the mControlItemList below and replace it.
106     mControlList.push_back( std::pair< Dali::Toolkit::Control, Dali::AutofillItem >( control, item ) );
107
108     // Push back a Control to the list
109     mControlItemList.push_back( control );
110   }
111 }
112
113 void AutofillContainer::RemoveAutofillItem( Dali::Toolkit::Control control )
114 {
115   if( control )
116   {
117     Internal::Control& controlImpl = GetImplementation( control );
118     Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
119     controlDataImpl.SetAutofillEnabled( false );
120     // TODO : Put the control out the list
121   }
122 }
123
124 Dali::AutofillGroup AutofillContainer::GetAutofillGroup()
125 {
126   return mAutofillGroup;
127 }
128
129 void AutofillContainer::SetFocusedControl( Toolkit::Control focused )
130 {
131   mCurrentFocused = focused;
132 }
133
134 Toolkit::Control AutofillContainer::GetFocusedControl()
135 {
136   return mCurrentFocused;
137 }
138
139 void AutofillContainer::SaveAutofillData()
140 {
141   for( std::vector<Dali::Toolkit::Control>::iterator iter = mControlItemList.begin(), endIter = mControlItemList.end(); iter != endIter; ++iter )
142   {
143     std::string controlValue = (*iter).GetProperty<std::string>( mPropertyIndex );
144     Internal::Control& controlImpl = GetImplementation( *iter );
145     Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
146     controlDataImpl.GetAutofillItemHandle().SetSaveValue( controlValue );
147   }
148
149   // Sends request to save the current autofill data
150   mAutofillGroup.SaveAutofillData();
151   mAutofillManager.SaveAutofillData( mAutofillGroup );
152 }
153
154 void AutofillContainer::RequestFillData()
155 {
156   // Sends fill request to fill out the data.
157   mAutofillGroup.SendFillRequest();
158 }
159
160 void AutofillContainer::SetAutofillServiceName( const std::string& serviceName )
161 {
162   mAutofillServiceName = serviceName;
163 }
164
165 const std::string& AutofillContainer::GetAutofillServiceName() const
166 {
167   return mAutofillServiceName;
168 }
169
170 void AutofillContainer::SetAutofillServiceMessage( const std::string& serviceMessage )
171 {
172   mAutofillServiceMessage = serviceMessage;
173 }
174
175 const std::string& AutofillContainer::GetAutofillServiceMessage() const
176 {
177   return mAutofillServiceMessage;
178 }
179
180 void AutofillContainer::SetAutofillServiceImagePath( const std::string& serviceImagePath )
181 {
182   mAutofillServiceImagePath = serviceImagePath;
183 }
184
185 const std::string& AutofillContainer::GetAutofillServiceImagePath() const
186 {
187   return mAutofillServiceImagePath;
188 }
189
190 unsigned int AutofillContainer::GetListCount()
191 {
192   Toolkit::Control control = mCurrentFocused;
193   Internal::Control& controlImpl = GetImplementation( control );
194   Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
195   return controlDataImpl.GetAutofillItemHandle().GetFillValueCount();
196 }
197
198 const std::string& AutofillContainer::GetListItem( unsigned int index ) const
199 {
200   Toolkit::Control control = mCurrentFocused;
201   Internal::Control& controlImpl = GetImplementation( control );
202   Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
203   return controlDataImpl.GetAutofillItemHandle().GetPresentationText( index );
204 }
205
206 void AutofillContainer::SetSelectedItem( const std::string& selected )
207 {
208   Toolkit::Control control = mCurrentFocused;
209   Internal::Control& controlImpl = GetImplementation( control );
210   Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
211   unsigned int count = controlDataImpl.GetAutofillItemHandle().GetFillValueCount();
212   unsigned int index = 0;
213   for( index = 0; index < count; index++ )
214   {
215     std::string presentationText =  controlDataImpl.GetAutofillItemHandle().GetPresentationText( index );
216     if( 0 == strcmp( presentationText.c_str(), selected.c_str() ) )
217     {
218       break;
219     }
220   }
221
222   for( std::vector<Dali::Toolkit::Control>::iterator iter = mControlItemList.begin(), endIter = mControlItemList.end(); iter != endIter; ++iter )
223   {
224     Internal::Control& controlImpl = GetImplementation( *iter );
225     Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
226     std::string fillValue = controlDataImpl.GetAutofillItemHandle().GetFillValue( index );
227     (*iter).SetProperty( Toolkit::TextField::Property::TEXT, fillValue );
228   }
229 }
230
231 //
232 void AutofillContainer::OnAutofillAuthReceived()
233 {
234   SetAutofillServiceName( mAutofillManager.GetAuthenticationServiceName() );
235   SetAutofillServiceMessage( mAutofillManager.GetAuthenticationServiceMessage() );
236   SetAutofillServiceImagePath( mAutofillManager.GetAuthenticationServiceImagePath() );
237
238   Dali::Toolkit::AutofillContainer handle( this );
239   mAuthenticationEventSignal.Emit( handle );
240
241   DALI_LOG_ERROR(" [ Emit DALi signal to receive the auth information ] \n");
242
243 }
244
245 void AutofillContainer::OnDataFillReceived( Dali::AutofillItem item )
246 {
247   for( std::vector<Dali::Toolkit::Control>::iterator iter = mControlItemList.begin(), endIter = mControlItemList.end(); iter != endIter; ++iter )
248   {
249     Internal::Control& controlImpl = GetImplementation( *iter );
250     Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
251
252     if( 0 == strcmp( controlDataImpl.GetAutofillItemHandle().GetId().c_str(), item.GetId().c_str() ) )
253     {
254       // TODO : Is the index for fill data always 0 in this case?
255       std::string itemText = controlDataImpl.GetAutofillItemHandle().GetFillValue( 0 );
256       (*iter).SetProperty( Toolkit::TextField::Property::TEXT, itemText );
257     }
258   }
259
260 }
261
262 void AutofillContainer::OnListReceived()
263 {
264   mListEventSignal.Emit( mCurrentFocused );
265
266 }
267
268
269 AutofillContainer::AutofillContainer()
270 : mAutofillManager(),
271   mAutofillGroup(),
272   mControlItemList(),
273   mControlList(),
274   mSlotDelegate( this ),
275   mPropertyIndex( Property::INVALID_INDEX ),
276   mAutofillServiceName( "" ),
277   mAutofillServiceMessage( "" ),
278   mAutofillServiceImagePath( "" ),
279   mCurrentFocused()
280 {
281 }
282
283 AutofillContainer::~AutofillContainer()
284 {
285   mAutofillManager.AuthenticationReceivedSignal().Disconnect( mSlotDelegate, &AutofillContainer::OnAutofillAuthReceived );
286   mAutofillManager.FillResponseReceivedSignal().Disconnect( mSlotDelegate, &AutofillContainer::OnDataFillReceived );
287   mAutofillManager.ListEventSignal().Disconnect( mSlotDelegate, &AutofillContainer::OnListReceived );
288 }
289
290 // Signals
291 Toolkit::AutofillContainer::AuthenticationSignalType& AutofillContainer::AutofillServiceShownSignal()
292 {
293   return mAuthenticationEventSignal;
294 }
295
296 Toolkit::AutofillContainer::ListShownSignalType& AutofillContainer::AutofillListShownSignal()
297 {
298   return mListEventSignal;
299 }
300
301 bool AutofillContainer::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
302 {
303   Dali::BaseHandle handle( object );
304
305   bool connected( true );
306   Toolkit::AutofillContainer container = Toolkit::AutofillContainer::DownCast( handle );
307
308   if( container )
309   {
310     if( 0 == signalName.compare( SIGNAL_SERVICE_SHOWN ) )
311     {
312       container.AutofillServiceShownSignal().Connect( tracker, functor );
313     }
314     else if( 0 == signalName.compare( SIGNAL_LIST_SHOWN ) )
315     {
316       container.AutofillListShownSignal().Connect( tracker, functor );
317     }
318     else
319     {
320       // signalName does not match any signal
321       connected = false;
322     }
323   }
324
325   return connected;
326 }
327
328 } // namespace Internal
329
330 } // namespace Toolkit
331
332 } // namespace Dali