Changed indicator bg color.
[platform/framework/native/uifw.git] / src / ui / controls / FUiCtrl_ListViewModel.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FUiCtrl_ListViewModel.cpp
20  * @brief       This is the implementation file for _ListViewModel class.
21  *
22  * This file contains the implementation of _ListViewModel class.
23  */
24
25 #include <FBaseSysLog.h>
26 #include "FUiCtrl_IListItemProviderAdaptor.h"
27 #include "FUiCtrl_IListItemCommon.h"
28 #include "FUiCtrl_ListViewModel.h"
29
30 namespace Tizen { namespace Ui { namespace Controls
31 {
32
33 _ListViewModel::_ListViewModel(void)
34         : __pListProviderAdaptor(null)
35         , __pTemporaryItemBuffer(null)
36         , __countOfAllGroups(0)
37         , __countOfAllItems(0)
38         , __indexOfFocusedGroup(-1)
39         , __indexOfFocusedItem(-1)
40         , __sizeOfCachingItems(CACHE_SIZE)
41         , __overflowItemsRemovingEnabled(true)
42         , __onRemovingAllItems(false)
43         , __pListViewModelDelegate(null)
44 {
45
46 }
47
48 _ListViewModel::~_ListViewModel(void)
49 {
50         if (__pTemporaryItemBuffer != null)
51         {
52                 int temporaryGroupIndex = -1;
53                 int temporaryItemIndex = -1;
54                 __pTemporaryItemBuffer->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
55
56                 __pListProviderAdaptor->DeleteItem(__pTemporaryItemBuffer, temporaryGroupIndex, temporaryItemIndex);
57                 __pTemporaryItemBuffer = null;
58         }
59
60         if (!__backupGroupNodes.empty())
61         {
62                 _ListViewGroupNode* pBackupedListGroupNode = null;
63                 int count = __backupGroupNodes.size();
64                 for (int i = 0; i < count; i++)
65                 {
66                         pBackupedListGroupNode = __backupGroupNodes.back();
67                         __backupGroupNodes.pop_back();
68
69                         delete pBackupedListGroupNode;
70                 }
71         }
72
73         DeleteAllGroupAndItem();
74 }
75
76 _IListItemProviderAdaptor*
77 _ListViewModel::GetItemProviderAdaptor(void) const
78 {
79         return __pListProviderAdaptor;
80 }
81
82 result
83 _ListViewModel::RegisterItemProviderAdaptor(const _IListItemProviderAdaptor* pProviderAdaptor)
84 {
85         SysTryReturn(NID_UI_CTRL, pProviderAdaptor != null, E_INVALID_ARG, E_INVALID_ARG,
86                                 "[E_INVALID_ARG] pProviderAdaptor is null.");
87
88         if (__pListProviderAdaptor != null)
89         {
90                 RemoveAllItem(false);
91         }
92
93         __pListProviderAdaptor = const_cast<_IListItemProviderAdaptor*>(pProviderAdaptor);
94
95         return E_SUCCESS;
96 }
97
98 result
99 _ListViewModel::SetGroupExpandState(int groupIndex, bool state)
100 {
101         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
102         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
103                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
104
105         pListGroupNode->__itemExpanded = state;
106
107         return E_SUCCESS;
108 }
109
110 bool
111 _ListViewModel::IsGroupExpanded(int groupIndex) const
112 {
113         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
114         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, false, GetLastResult(),
115                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
116
117         return pListGroupNode->__itemExpanded;
118 }
119
120 _IListItemCommon*
121 _ListViewModel::GetItemFromTemporaryBuffer(int groupIndex, int itemIndex)
122 {
123         if (__onRemovingAllItems)
124         {
125                 return null;
126         }
127
128         int temporaryGroupIndex = -1;
129         int temporaryItemIndex = -1;
130         if (__pTemporaryItemBuffer != null)
131         {
132                 __pTemporaryItemBuffer->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
133                 if (groupIndex == temporaryGroupIndex && itemIndex == temporaryItemIndex)
134                 {
135                         return __pTemporaryItemBuffer;
136                 }
137         }
138
139         _IListItemCommon* pItem = GetItemFromContainer(groupIndex, itemIndex);
140
141         if (pItem == null)
142         {
143                 __pListProviderAdaptor->UnloadItem(__pTemporaryItemBuffer, temporaryGroupIndex, temporaryItemIndex);
144                 __pTemporaryItemBuffer = __pListProviderAdaptor->LoadItem(groupIndex, itemIndex);
145                 if (__pTemporaryItemBuffer != null)
146                 {
147                         __pTemporaryItemBuffer->SetItemIndex(groupIndex, itemIndex);
148                 }
149         }
150         else if (__pTemporaryItemBuffer != null && __pTemporaryItemBuffer != pItem)
151         {
152                 __pListProviderAdaptor->UnloadItem(__pTemporaryItemBuffer, temporaryGroupIndex, temporaryItemIndex);
153                 __pTemporaryItemBuffer = null;
154
155                 return pItem;
156         }
157         else
158         {
159                 __pTemporaryItemBuffer = null;
160
161                 return pItem;
162         }
163
164         return __pTemporaryItemBuffer;
165 }
166
167 _IListItemCommon*
168 _ListViewModel::GetItemFromContainer(int groupIndex, int itemIndex) const
169 {
170         if (groupIndex < 0 || groupIndex >= __countOfAllGroups)
171         {
172                 return null;
173         }
174
175         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
176         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, null, GetLastResult(),
177                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
178
179         int temporaryGroupIndex = -1;
180         int temporaryItemIndex = -1;
181
182         _IListItemCommon* pItem = null;
183         _LinkedList <_IListItemCommon*>::_Iterator theIter = pListGroupNode->__items.begin();
184         _LinkedList <_IListItemCommon*>::_Iterator theEndIter = pListGroupNode->__items.end();
185
186         while (theIter != theEndIter)
187         {
188                 pItem = *theIter;
189                 pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
190
191                 if (temporaryItemIndex == itemIndex)
192                 {
193                         return pItem;
194                 }
195                 else if (temporaryItemIndex > itemIndex)
196                 {
197                         break;
198                 }
199
200                 theIter++;
201         }
202
203         return null;
204 }
205
206 _IListItemCommon*
207 _ListViewModel::LoadItem(int groupIndex, int itemIndex)
208 {
209         if (__onRemovingAllItems)
210         {
211                 return null;
212         }
213
214         // check validation of groupIndex
215         if (groupIndex < 0 || groupIndex >= __countOfAllGroups)
216         {
217                 return null;
218         }
219
220         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
221         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, null, GetLastResult(),
222                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
223
224         // check validation of item index
225         if (itemIndex < -1 || itemIndex >= pListGroupNode->__itemCountInGroup)
226         {
227                 return null;
228         }
229
230         // load item
231         _IListItemCommon* pItemCommon = GetItemFromContainer(groupIndex, itemIndex);
232         if (pItemCommon == null)
233         {
234                 pItemCommon = __pListProviderAdaptor->LoadItem(groupIndex, itemIndex);
235                 if (pItemCommon != null)
236                 {
237                         pItemCommon->SetChecked(IsItemChecked(groupIndex, itemIndex));
238                         pItemCommon->SetItemEnabled(IsItemEnabled(groupIndex, itemIndex));
239                         pItemCommon->SetItemIndex(groupIndex, itemIndex);
240
241                         LoadItemToContainer(groupIndex, itemIndex, *pItemCommon);
242                 }
243         }
244
245         return pItemCommon;
246 }
247
248 result
249 _ListViewModel::LoadItemToContainer(int groupIndex, int itemIndex, _IListItemCommon& item)
250 {
251         _ListViewGroupNode* pListGroupNode = __groupNodes.at(groupIndex);
252         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
253                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
254
255         int overCount = 0;
256         bool pushToTopOrMiddle = true;
257
258         if (pListGroupNode->__items.empty())
259         {
260                 int loadedGroups = GetAllGroupCount();
261                 _ListViewGroupNode* pTemporaryGroupNode = null;
262                 for (int i = loadedGroups - 1; i >= 0; i--)
263                 {
264                         pTemporaryGroupNode = GetGroupNode(i);
265                         if (pTemporaryGroupNode != null)
266                         {
267                                 if (i > groupIndex)
268                                 {
269                                         if (pTemporaryGroupNode->__items.size() > 0)
270                                         {
271                                                 break;
272                                         }
273                                 }
274                                 else
275                                 {
276                                         pushToTopOrMiddle = false;
277                                         break;
278                                 }
279                         }
280                 }
281         }
282         else
283         {
284                 int temporaryGroupIndex = -1;
285                 int temporaryItemIndex = -1;
286                 _IListItemCommon* pItem = null;
287                 _LinkedList <_IListItemCommon*>::_Iterator theIter = pListGroupNode->__items.begin();
288                 _LinkedList <_IListItemCommon*>::_Iterator theEndIter = pListGroupNode->__items.end();
289                 while (theIter != theEndIter)
290                 {
291                         pItem = *theIter;
292                         pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
293
294                         if (temporaryItemIndex == itemIndex)
295                         {
296                                 return E_SUCCESS;
297                         }
298                         else if (temporaryItemIndex > itemIndex)
299                         {
300                                 // push item to top or middle
301                                 pListGroupNode->__items.insert(theIter, &item);
302
303                                 overCount = GetOverflowCount();
304                                 if (overCount > 0)
305                                 {
306                                         if (__pListViewModelDelegate != null && __pListViewModelDelegate->OnOcurredOverflowItems(__sizeOfCachingItems, overCount))
307                                         {
308                                                 __sizeOfCachingItems += overCount;
309                                         }
310                                         else
311                                         {
312                                                 RemoveOverflowItems(true, overCount);
313                                         }
314                                 }
315
316                                 return E_SUCCESS;
317                         }
318                         ++theIter;
319                 }
320
321                 int lastLoadedItemIndex = -1;
322                 int lastLoadedGroupIndex = -1;
323                 GetLastLoadedItemIndex(lastLoadedGroupIndex, lastLoadedItemIndex);
324                 if (lastLoadedGroupIndex == temporaryGroupIndex && lastLoadedItemIndex == temporaryItemIndex)
325                 {
326                         pushToTopOrMiddle = false;
327                 }
328                 else
329                 {
330                         pushToTopOrMiddle = true;
331                 }
332         }
333
334         // push item to bottom
335         pListGroupNode->__items.push_back(&item);
336
337         overCount = GetOverflowCount();
338         if (overCount > 0)
339         {
340                 // if push item to end of list, RemoveOverflowItems() from top.
341                 if (__pListViewModelDelegate != null && __pListViewModelDelegate->OnOcurredOverflowItems(__sizeOfCachingItems, overCount))
342                 {
343                         __sizeOfCachingItems += overCount;
344                 }
345                 else
346                 {
347                         RemoveOverflowItems(pushToTopOrMiddle, overCount);
348                 }
349         }
350
351         return E_SUCCESS;
352 }
353
354 void
355 _ListViewModel::SetListViewModelDelegate(_IListViewModelDelegate* pDelegate)
356 {
357         __pListViewModelDelegate = pDelegate;
358 }
359
360 bool
361 _ListViewModel::IsValidItem(int groupIndex, int itemIndex) const
362 {
363         // check validation of groupIndex
364         if (groupIndex < 0 || groupIndex >= __countOfAllGroups)
365         {
366                 return false;
367         }
368
369         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
370         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, false, GetLastResult(),
371                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
372
373         // check validation of item index
374         if (itemIndex < -1 || itemIndex >= pListGroupNode->__itemCountInGroup)
375         {
376                 return false;
377         }
378
379         return true;
380 }
381
382 bool
383 _ListViewModel::IsLoadedItem(int groupIndex, int itemIndex) const
384 {
385         // check validation of groupIndex
386         if (groupIndex < 0 || groupIndex >= __countOfAllGroups)
387         {
388                 return false;
389         }
390
391         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
392         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, false, GetLastResult(),
393                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
394
395         // check validation of item index
396         if (itemIndex < -1 || itemIndex >= pListGroupNode->__itemCountInGroup)
397         {
398                 return false;
399         }
400
401         int temporaryGroupIndex = -1;
402         int temporaryItemIndex = -1;
403
404         _IListItemCommon* pItem = null;
405         _LinkedList <_IListItemCommon*>::_Iterator theIter = pListGroupNode->__items.begin();
406         _LinkedList <_IListItemCommon*>::_Iterator theEndIter = pListGroupNode->__items.end();
407
408         while (theIter != theEndIter)
409         {
410                 pItem = *theIter;
411                 pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
412
413                 if (temporaryItemIndex == itemIndex)
414                 {
415                         return true;
416                 }
417                 else if (temporaryItemIndex > itemIndex)
418                 {
419                         return false;
420                 }
421
422                 theIter++;
423         }
424
425         return false;
426 }
427
428 result
429 _ListViewModel::AddGroup(int itemCount, bool usingRadioStyle)
430 {
431         SysTryReturn(NID_UI_CTRL, itemCount >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The itemCount is not valid.");
432
433         //Create new GroupNode
434         _ListViewGroupNode* pListGroupNode = new (std::nothrow) _ListViewGroupNode();
435         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
436                                  "[E_OUT_OF_MEMORY] The memory is insufficient.");
437
438         pListGroupNode->__itemCountInGroup = itemCount;
439         pListGroupNode->__usingRadioStyle = usingRadioStyle;
440
441         __groupNodes.push_back(pListGroupNode);
442
443         __countOfAllItems = __countOfAllItems + itemCount + 1;  // include groupItem
444         __countOfAllGroups++;
445
446         return E_SUCCESS;
447 }
448
449 result
450 _ListViewModel::InsertGroup(int groupIndex, int itemCount, bool usingRadioStyle)
451 {
452         // check validation of groupIndex
453         SysTryReturn(NID_UI_CTRL, (groupIndex >= 0 && groupIndex <= __countOfAllGroups), E_INVALID_ARG, E_INVALID_ARG,
454                                 "[E_INVALID_ARG] Wrong group index(%d).", groupIndex);
455
456         SysTryReturn(NID_UI_CTRL, itemCount >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The itemCount is not valid.");
457
458         if (__groupNodes.empty() || groupIndex == GetAllGroupCount())
459         {
460                 return AddGroup(itemCount);
461         }
462
463         //Create new GroupNode
464         _ListViewGroupNode* pListGroupNode = new (std::nothrow) _ListViewGroupNode();
465         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
466                                  "[E_OUT_OF_MEMORY] The memory is insufficient.");
467
468         pListGroupNode->__itemCountInGroup = itemCount;
469         pListGroupNode->__usingRadioStyle = usingRadioStyle;
470
471         __groupNodes.insert(__groupNodes.begin() + groupIndex, pListGroupNode);
472
473         __countOfAllItems = __countOfAllItems + itemCount + 1;  // include groupItem
474         __countOfAllGroups++;
475
476         // item index reordering
477         int groupCount = GetAllGroupCount();
478         int temporaryGroupIndex = -1;
479         int temporaryItemIndex = -1;
480
481         pListGroupNode = null;
482         _IListItemCommon* pItem = null;
483
484         for (int i = groupCount - 1; i > groupIndex; i--)
485         {
486                 pListGroupNode = GetGroupNode(i);
487                 if (pListGroupNode != null)
488                 {
489                         for (int j = pListGroupNode->__items.size() - 1; j >= 0; j--)
490                         {
491                                 pItem = pListGroupNode->__items.at(j);
492                                 if (pItem != null)
493                                 {
494                                         pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
495                                         pItem->SetItemIndex(i, temporaryItemIndex);
496                                 }
497                         }
498                 }
499         }
500
501         return E_SUCCESS;
502 }
503
504 result
505 _ListViewModel::UnloadAllItem(void)
506 {
507         if (__groupNodes.empty())
508         {
509                 return E_SUCCESS;
510         }
511
512         int groupCount = GetAllGroupCount();
513         int itemCount = 0;
514
515         _ListViewGroupNode* pListGroupNode = null;
516         _IListItemCommon* pItem = null;
517
518         int groupIndex = -1;
519         int itemIndex = -1;
520         for (int i = groupCount - 1; i >= 0; i--)
521         {
522                 pListGroupNode = GetGroupNode(i);
523                 if (pListGroupNode != null)
524                 {
525                         itemCount = pListGroupNode->__items.size();
526                         for (int j = itemCount - 1; j >= 0; j--)
527                         {
528                                 pItem = pListGroupNode->__items.back();
529                                 pListGroupNode->__items.pop_back();
530
531                                 if (pItem != null)
532                                 {
533                                         pItem->GetItemIndex(groupIndex, itemIndex);
534                                         __pListProviderAdaptor->UnloadItem(pItem, groupIndex, itemIndex);
535                                 }
536                         }
537                 }
538         }
539
540         return E_SUCCESS;
541 }
542
543 result
544 _ListViewModel::DeleteAllGroupAndItem(void)
545 {
546         return RemoveAllItem(true);
547 }
548
549 result
550 _ListViewModel::RemoveAllItem(bool internalDestroy, bool backupItemStatus)
551 {
552         if (__groupNodes.empty())
553         {
554                 return E_SUCCESS;
555         }
556
557         __onRemovingAllItems = true;
558
559         _LinkedList <_ListViewGroupNode*> backupGroupNodes;
560         backupGroupNodes = __groupNodes;
561
562         __countOfAllGroups = 0;
563         __countOfAllItems = 0;
564
565         int groupCount = backupGroupNodes.size();
566         int itemCount = 0;
567
568         _ListViewGroupNode* pListGroupNode = null;
569         _IListItemCommon* pItem = null;
570
571         int groupIndex = -1;
572         int itemIndex = -1;
573         for (int i = groupCount - 1; i >= 0; i--)
574         {
575                 pListGroupNode = backupGroupNodes.at(i);
576
577                 if (pListGroupNode != null)
578                 {
579                         itemCount = pListGroupNode->__items.size();
580
581                         for (int j = itemCount - 1; j >= 0; j--)
582                         {
583                                 pItem = pListGroupNode->__items.back();
584                                 pListGroupNode->__items.pop_back();
585
586                                 if (pItem != null)
587                                 {
588                                         pItem->GetItemIndex(groupIndex, itemIndex);
589
590                                         if (!internalDestroy)
591                                         {
592                                                 __pListProviderAdaptor->UnloadItem(pItem, groupIndex, itemIndex);
593                                         }
594                                         else
595                                         {
596                                                 __pListProviderAdaptor->DeleteItem(pItem, groupIndex, itemIndex);
597                                         }
598                                 }
599                         }
600
601                         pListGroupNode->__itemCountInGroup = 0;
602
603                         if (!backupItemStatus)
604                         {
605                                 __groupNodes.remove(pListGroupNode);
606                                 delete pListGroupNode;
607                                 pListGroupNode = null;
608                         }
609                 }
610         }
611
612         if (backupItemStatus)
613         {
614                 __backupGroupNodes = backupGroupNodes;
615         }
616
617         __onRemovingAllItems = false;
618         return E_SUCCESS;
619 }
620
621 void
622 _ListViewModel::RestoreItemStatus(void)
623 {
624         if (__backupGroupNodes.empty())
625         {
626                 return;
627         }
628
629         _ListViewGroupNode* pListGroupNode = null;
630         _ListViewGroupNode* pBackupedListGroupNode = null;
631
632         for (int i = 0; i < __backupGroupNodes.size(); i++)
633         {
634                 pListGroupNode = GetGroupNode(i);
635                 pBackupedListGroupNode = __backupGroupNodes.at(i);
636
637                 if (pListGroupNode != null)
638                 {
639                         pListGroupNode->__checkedItems = pBackupedListGroupNode->__checkedItems;
640                         pListGroupNode->__disabledItems = pBackupedListGroupNode->__disabledItems;
641                         pListGroupNode->__itemExpanded = pBackupedListGroupNode->__itemExpanded;
642                 }
643
644                 delete pBackupedListGroupNode;
645         }
646
647         __backupGroupNodes.clear();
648 }
649
650
651 result
652 _ListViewModel::UnloadItem(int groupIndex, int itemIndex)
653 {
654         // check validation of groupIndex
655         SysTryReturn(NID_UI_CTRL, (groupIndex >= 0 && groupIndex < __countOfAllGroups), E_INVALID_ARG, E_INVALID_ARG,
656                                 "[E_INVALID_ARG] Wrong group index(%d).", groupIndex);
657
658         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
659         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
660                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
661
662         int temporaryGroupIndex = -1;
663         int temporaryItemIndex = -1;
664
665         _IListItemCommon* pItem = null;
666         _LinkedList <_IListItemCommon*>::_Iterator theIter = pListGroupNode->__items.begin();
667         _LinkedList <_IListItemCommon*>::_Iterator theEndIter = pListGroupNode->__items.end();
668
669         while (theIter != theEndIter)
670         {
671                 pItem = *theIter;
672                 pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
673
674                 if (temporaryItemIndex == itemIndex)
675                 {
676                         pListGroupNode->__items.erase(theIter);
677
678                         __pListProviderAdaptor->UnloadItem(pItem, groupIndex, itemIndex);
679
680                         return E_SUCCESS;
681                 }
682
683                 theIter++;
684         }
685
686         return E_SUCCESS;
687 }
688
689 result
690 _ListViewModel::RemoveItemAt(int groupIndex, int itemIndex, bool internalDestroy)
691 {
692         // check validation of groupIndex
693         SysTryReturn(NID_UI_CTRL, (groupIndex >= 0 && groupIndex < __countOfAllGroups), E_INVALID_ARG, E_INVALID_ARG,
694                                 "[E_INVALID_ARG] Wrong group index(%d).", groupIndex);
695
696         if (itemIndex == -1)
697         {
698                 return RemoveGroup(groupIndex);
699         }
700
701         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
702         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
703                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
704
705
706         _IListItemCommon* pItem = GetItemFromContainer(groupIndex, itemIndex);
707
708         int temporaryGroupIndex = -1;
709         int temporaryItemIndex = -1;
710         _IListItemCommon* pTemporaryItem = null;
711         _LinkedList <_IListItemCommon*>::_Iterator theIter = pListGroupNode->__items.begin();
712         while (theIter != pListGroupNode->__items.end())
713         {
714                 pTemporaryItem = *theIter;
715                 pTemporaryItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
716
717                 if (temporaryItemIndex > itemIndex)
718                 {
719                         pTemporaryItem->SetItemIndex(temporaryGroupIndex, temporaryItemIndex - 1);
720                 }
721
722                 theIter++;
723         }
724
725         MoveCheckedAndDisabledItemIndex(pListGroupNode, itemIndex, -1);
726
727         pListGroupNode->__itemCountInGroup--;
728         __countOfAllItems--;
729
730         if (pItem != null)
731         {
732                 pListGroupNode->__items.remove(pItem);
733                 if (internalDestroy == false)
734                 {
735                         __pListProviderAdaptor->UnloadItem(pItem, groupIndex, itemIndex);
736                 }
737                 else
738                 {
739                         __pListProviderAdaptor->DeleteItem(pItem, groupIndex, itemIndex);
740                 }
741         }
742
743         return E_SUCCESS;
744 }
745
746 result
747 _ListViewModel::RemoveGroup(int groupIndex)
748 {
749         // check validation of groupIndex
750         SysTryReturn(NID_UI_CTRL, (groupIndex >= 0 && groupIndex < __countOfAllGroups), E_INVALID_ARG, E_INVALID_ARG,
751                                 "[E_INVALID_ARG] Wrong group index(%d).", groupIndex);
752
753         _ListViewGroupNode* pRemoveGroupNode = GetGroupNode(groupIndex);
754         SysTryReturn(NID_UI_CTRL, pRemoveGroupNode != null, GetLastResult(), GetLastResult(),
755                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
756
757         // remove group from model
758         __groupNodes.erase(__groupNodes.begin() + groupIndex);
759
760         __countOfAllItems -= (pRemoveGroupNode->__itemCountInGroup + 1);
761         __countOfAllGroups--;
762
763         _IListItemCommon* pItem = null;
764         _ListViewGroupNode* pListGroupNode = null;
765
766         int itemCount = 0;
767         int temporaryGroupIndex = -1;
768         int temporaryItemIndex = -1;
769
770         // reset item index
771         int groupCount = __groupNodes.size();
772         for (int i = groupCount - 1; i >= groupIndex; i--)
773         {
774                 pListGroupNode = GetGroupNode(i);
775
776                 if (pListGroupNode != null)
777                 {
778                         itemCount = pListGroupNode->__items.size();
779
780                         for (int j = itemCount - 1; j >= 0; j--)
781                         {
782                                 pItem = pListGroupNode->__items.at(j);
783
784                                 if (pItem != null)
785                                 {
786                                         pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
787                                         pItem->SetItemIndex(temporaryGroupIndex - 1, temporaryItemIndex);
788                                 }
789                         }
790                 }
791         }
792
793         // remove group
794         itemCount = pRemoveGroupNode->__items.size();
795
796         for (int i = itemCount - 1; i >= 0; i--)
797         {
798                 pItem = pRemoveGroupNode->__items.at(i);
799                 pRemoveGroupNode->__items.pop_back();
800
801                 if (pItem != null)
802                 {
803                         pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
804                         __pListProviderAdaptor->UnloadItem(pItem, temporaryGroupIndex, temporaryItemIndex);
805                 }
806         }
807
808         delete pRemoveGroupNode;
809
810         return E_SUCCESS;
811 }
812
813 result
814 _ListViewModel::SetMaxCachingSize(int cachingSize)
815 {
816         SysTryReturn(NID_UI_CTRL, cachingSize > 0, E_INVALID_ARG, E_INVALID_ARG,
817                                 "[E_INVALID_ARG] Wrong cachingSize(%d).", cachingSize);
818
819         __sizeOfCachingItems = cachingSize;
820
821         return E_SUCCESS;
822 }
823
824 int
825 _ListViewModel::GetMaxCachingSize(void) const
826 {
827         return __sizeOfCachingItems;
828 }
829
830 int
831 _ListViewModel::GetOverflowCount(void) const
832 {
833         int loadedItems = 0;
834         int loadedGroups = __groupNodes.size();
835
836         _ListViewGroupNode* pListGroupNode = null;
837         for (int i = 0; i < loadedGroups; i++)
838         {
839                 pListGroupNode = __groupNodes.at(i);
840                 if (pListGroupNode != null)
841                 {
842                         loadedItems += pListGroupNode->__items.size();
843                 }
844         }
845
846         if (__sizeOfCachingItems < loadedItems)
847         {
848                 return loadedItems - __sizeOfCachingItems;
849         }
850
851         return 0;
852 }
853
854 result
855 _ListViewModel::RemoveOverflowItems(bool deleteFromEnd, int removeCount)
856 {
857         SysTryReturn(NID_UI_CTRL, (removeCount > 0 && removeCount < __sizeOfCachingItems), E_INVALID_ARG, E_INVALID_ARG,
858                                 "[E_INVALID_ARG] removeCount should be greater than 0.");
859
860         if (__overflowItemsRemovingEnabled == false)
861         {
862                 return E_SUCCESS;
863         }
864
865         int loadedGroups = GetAllGroupCount();
866         int temporaryGroupIndex = -1;
867         int temporaryItemIndex = -1;
868         int loadedItems = 0;
869         int i = 0;
870         int j = 0;
871
872         _ListViewGroupNode* pListGroupNode = null;
873         _IListItemCommon* pItem = null;
874
875         // remove priority : collapsed group items
876         for (i = 0; i < loadedGroups; i++)
877         {
878                 pListGroupNode = GetGroupNode(i);
879                 if (pListGroupNode != null)
880                 {
881                         if (pListGroupNode->__itemExpanded == false)
882                         {
883                                 loadedItems = pListGroupNode->__items.size();
884                                 for (j = 0; j < loadedItems; j++)
885                                 {
886                                         pItem = pListGroupNode->__items.back();
887                                         pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
888
889                                         if (temporaryItemIndex == -1)
890                                         {
891                                                 break;
892                                         }
893
894                                         pListGroupNode->__items.pop_back();
895                                         __pListProviderAdaptor->UnloadItem(pItem, temporaryGroupIndex, temporaryItemIndex);
896
897                                         if (--removeCount <= 0)
898                                         {
899                                                 return E_SUCCESS;
900                                         }
901                                 }
902                         }
903                 }
904         }
905
906         if (deleteFromEnd == true)
907         {
908                 for (i = loadedGroups - 1; i >= 0; i--)
909                 {
910                         pListGroupNode = GetGroupNode(i);
911                         if (pListGroupNode != null)
912                         {
913                                 loadedItems = pListGroupNode->__items.size();
914                                 for (j = 0; j < loadedItems; j++)
915                                 {
916                                         pItem = pListGroupNode->__items.back();
917                                         pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
918
919                                         pListGroupNode->__items.pop_back();
920                                         __pListProviderAdaptor->UnloadItem(pItem, temporaryGroupIndex, temporaryItemIndex);
921
922                                         if (--removeCount <= 0)
923                                         {
924                                                 return E_SUCCESS;
925                                         }
926                                 }
927                         }
928                 }
929         }
930         else
931         {
932                 for (i = 0; i < loadedGroups; i++)
933                 {
934                         pListGroupNode = GetGroupNode(i);
935                         if (pListGroupNode != null)
936                         {
937                                 loadedItems = pListGroupNode->__items.size();
938                                 for (j = 0; j < loadedItems; j++)
939                                 {
940                                         pItem = pListGroupNode->__items.front();
941                                         pItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
942
943                                         pListGroupNode->__items.pop_front();
944                                         __pListProviderAdaptor->UnloadItem(pItem, temporaryGroupIndex, temporaryItemIndex);
945
946                                         if (--removeCount <= 0)
947                                         {
948                                                 return E_SUCCESS;
949                                         }
950                                 }
951                         }
952                 }
953         }
954
955         return E_SUCCESS;
956 }
957
958 int
959 _ListViewModel::GetAllItemCount(void) const
960 {
961         return __countOfAllItems;
962 }
963
964 int
965 _ListViewModel::GetItemCountInGroup(int groupIndex) const
966 {
967         // check validation of groupIndex
968         if (groupIndex < 0 || groupIndex >= __countOfAllGroups)
969         {
970                 return -1;
971         }
972
973         int itemCount = -1;
974
975         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
976
977         if (pListGroupNode == null)
978         {
979                 itemCount = __pListProviderAdaptor->GetItemCount(groupIndex);
980         }
981         else
982         {
983                 itemCount = pListGroupNode->__itemCountInGroup;
984         }
985
986         return itemCount;
987 }
988
989 int
990 _ListViewModel::GetAllGroupCount(void) const
991 {
992         return __groupNodes.size();
993 }
994
995 void
996 _ListViewModel::GetFocusedItem(int& groupIndex, int& itemIndex) const
997 {
998         groupIndex = __indexOfFocusedGroup;
999         itemIndex = __indexOfFocusedItem;
1000 }
1001
1002 void
1003 _ListViewModel::SetFocusedItem(int groupIndex, int itemIndex)
1004 {
1005         __indexOfFocusedGroup = groupIndex;
1006         __indexOfFocusedItem = itemIndex;
1007 }
1008
1009 bool
1010 _ListViewModel::IsFocusedItem(int groupIndex, int itemIndex) const
1011 {
1012         if ((groupIndex == __indexOfFocusedGroup) && (itemIndex == __indexOfFocusedItem))
1013         {
1014                 return true;
1015         }
1016
1017         return false;
1018 }
1019
1020 result
1021 _ListViewModel::SetItemEnabled(int groupIndex, int itemIndex, bool enable)
1022 {
1023         // check validation
1024         if (IsValidItem(groupIndex, itemIndex) == false)
1025         {
1026                 return E_SYSTEM;
1027         }
1028
1029         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
1030         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
1031                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1032
1033         int disabledItem = itemIndex;
1034         bool findItem = false;
1035
1036         _LinkedList <int>::_Iterator theIter = pListGroupNode->__disabledItems.begin();
1037
1038         while (theIter != pListGroupNode->__disabledItems.end())
1039         {
1040                 if (*theIter == itemIndex)
1041                 {
1042                         if (enable == true)
1043                         {
1044                                 pListGroupNode->__disabledItems.erase(theIter);
1045                         }
1046                         findItem = true;
1047                         break;
1048                 }
1049                 else if (*theIter > itemIndex)
1050                 {
1051                         if (enable == false)
1052                         {
1053                                 pListGroupNode->__disabledItems.insert(theIter, disabledItem);
1054                         }
1055                         findItem = true;
1056                         break;
1057                 }
1058
1059                 theIter++;
1060         }
1061
1062         if (findItem == false && enable == false)
1063         {
1064                 pListGroupNode->__disabledItems.push_back(disabledItem);
1065         }
1066
1067         if (IsLoadedItem(groupIndex, itemIndex) == false)
1068         {
1069                 return E_SUCCESS;
1070         }
1071
1072         _IListItemCommon* pItem = GetItemFromContainer(groupIndex, itemIndex);
1073         if (pItem != null)
1074         {
1075                 pItem->SetItemEnabled(enable);
1076         }
1077
1078         return E_SUCCESS;
1079 }
1080
1081 bool
1082 _ListViewModel::IsItemEnabled(int groupIndex, int itemIndex) const
1083 {
1084         // check validation
1085         if (IsValidItem(groupIndex, itemIndex) == false)
1086         {
1087                 return false;
1088         }
1089
1090         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
1091         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, false, GetLastResult(),
1092                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1093
1094         _LinkedList <int>::_Iterator theIter = pListGroupNode->__disabledItems.begin();
1095
1096         while (theIter != pListGroupNode->__disabledItems.end())
1097         {
1098                 if (*theIter == itemIndex)
1099                 {
1100                         return false;
1101                 }
1102                 else if (*theIter > itemIndex)
1103                 {
1104                         break;
1105                 }
1106
1107                 theIter++;
1108         }
1109
1110         return true;
1111 }
1112
1113 result
1114 _ListViewModel::SetItemChecked(int groupIndex, int itemIndex, bool check)
1115 {
1116         // check validation
1117         if (IsValidItem(groupIndex, itemIndex) == false)
1118         {
1119                 return E_SYSTEM;
1120         }
1121
1122         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
1123         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
1124                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1125
1126         //radio style
1127         _IListItemCommon* pItem = null;
1128         if (pListGroupNode->__usingRadioStyle == true)
1129         {
1130                 if (check == true)
1131                 {
1132                         if (pListGroupNode->__radioCheckedItemIndex == itemIndex)
1133                         {
1134                                 return E_SUCCESS;
1135                         }
1136
1137                         pItem = GetItemFromContainer(groupIndex, pListGroupNode->__radioCheckedItemIndex);
1138                         if (pItem != null)
1139                         {
1140                                 pItem->SetChecked(false);
1141                         }
1142
1143                         pListGroupNode->__radioCheckedItemIndex = itemIndex;
1144
1145                         pItem = GetItemFromContainer(groupIndex, itemIndex);
1146                         if (pItem != null)
1147                         {
1148                                 pItem->SetChecked(true);
1149                         }
1150
1151                         return E_SUCCESS;
1152                 }
1153                 else
1154                 {
1155                         if (pListGroupNode->__radioCheckedItemIndex == itemIndex)
1156                         {
1157                                 pItem = GetItemFromContainer(groupIndex, pListGroupNode->__radioCheckedItemIndex);
1158                                 if (pItem != null)
1159                                 {
1160                                         pItem->SetChecked(false);
1161                                 }
1162
1163                                 pListGroupNode->__radioCheckedItemIndex = -1;
1164                         }
1165
1166                         return E_SUCCESS;
1167                 }
1168         }
1169
1170         int checkedItem = itemIndex;
1171         bool findItem = false;
1172
1173         _LinkedList <int>::_Iterator theIter = pListGroupNode->__checkedItems.begin();
1174         while (theIter != pListGroupNode->__checkedItems.end())
1175         {
1176                 if (*theIter == itemIndex)
1177                 {
1178                         if (check == false)
1179                         {
1180                                 pListGroupNode->__checkedItems.erase(theIter);
1181                         }
1182                         findItem = true;
1183                         break;
1184                 }
1185                 else if (*theIter > itemIndex)
1186                 {
1187                         if (check == true)
1188                         {
1189                                 pListGroupNode->__checkedItems.insert(theIter, checkedItem);
1190                         }
1191                         findItem = true;
1192                         break;
1193                 }
1194
1195                 theIter++;
1196         }
1197
1198         if (findItem == false && check == true)
1199         {
1200                 pListGroupNode->__checkedItems.push_back(checkedItem);
1201         }
1202
1203         if (IsLoadedItem(groupIndex, itemIndex) == false)
1204         {
1205                 return E_SUCCESS;
1206         }
1207
1208         pItem = GetItemFromContainer(groupIndex, itemIndex);
1209         if (pItem != null)
1210         {
1211                 pItem->SetChecked(check);
1212         }
1213
1214         return E_SUCCESS;
1215 }
1216
1217 bool
1218 _ListViewModel::IsItemChecked(int groupIndex, int itemIndex) const
1219 {
1220         // check validation
1221         if (!IsValidItem(groupIndex, itemIndex))
1222         {
1223                 return false;
1224         }
1225
1226         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
1227         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, false, GetLastResult(),
1228                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1229
1230         //radio style
1231         if (pListGroupNode->__usingRadioStyle)
1232         {
1233                 if (pListGroupNode->__radioCheckedItemIndex == itemIndex)
1234                 {
1235                         return true;
1236                 }
1237
1238                 return false;
1239         }
1240
1241         _LinkedList <int>::_Iterator theIter = pListGroupNode->__checkedItems.begin();
1242
1243         while (theIter != pListGroupNode->__checkedItems.end())
1244         {
1245                 if (*theIter == itemIndex)
1246                 {
1247                         return true;
1248                 }
1249                 else if (*theIter > itemIndex)
1250                 {
1251                         break;
1252                 }
1253
1254                 theIter++;
1255         }
1256
1257         return false;
1258 }
1259
1260 int
1261 _ListViewModel::GetIndexOfRadioCheckedItem(int groupIndex) const
1262 {
1263         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
1264         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, -1, GetLastResult(),
1265                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1266
1267         return pListGroupNode->__radioCheckedItemIndex;
1268 }
1269
1270 void
1271 _ListViewModel::SetAllLoadedItemStateChanged(bool state)
1272 {
1273         if (__groupNodes.empty() == true)
1274         {
1275                 return;
1276         }
1277
1278         int groupCount = GetAllGroupCount();
1279         _ListViewGroupNode* pListGroupNode = null;
1280         _IListItemCommon* pItem = null;
1281
1282         for (int i = 0; i < groupCount; i++)
1283         {
1284                 pListGroupNode = GetGroupNode(i);
1285                 SysTryReturnVoidResult(NID_UI_CTRL, pListGroupNode != null, GetLastResult(),
1286                                         "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1287
1288                 _LinkedList <_IListItemCommon*>::_Iterator theIter = pListGroupNode->__items.begin();
1289                 while (theIter != pListGroupNode->__items.end())
1290                 {
1291                         pItem = *theIter;
1292                         pItem->SetItemChanged(state);
1293
1294                         theIter++;
1295                 }
1296         }
1297 }
1298
1299 void
1300 _ListViewModel::GetFirstLoadedItemIndex(int& groupIndex, int& itemIndex) const
1301 {
1302         int groupCount = GetAllGroupCount();
1303         _ListViewGroupNode* pListGroupNode = null;
1304         _IListItemCommon* pItem = null;
1305
1306         for (int i = 0; i < groupCount; i++)
1307         {
1308                 pListGroupNode = GetGroupNode(i);
1309                 SysTryReturnVoidResult(NID_UI_CTRL, pListGroupNode != null, GetLastResult(),
1310                                         "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1311
1312                 if (pListGroupNode->__items.empty() == false)
1313                 {
1314                         pItem = pListGroupNode->__items.front();
1315                         pItem->GetItemIndex(groupIndex, itemIndex);
1316                         break;
1317                 }
1318         }
1319 }
1320
1321 void
1322 _ListViewModel::GetLastLoadedItemIndex(int& groupIndex, int& itemIndex) const
1323 {
1324         int groupCount = GetAllGroupCount();
1325         _ListViewGroupNode* pListGroupNode = null;
1326         _IListItemCommon* pItem = null;
1327
1328         for (int i = groupCount - 1; i >= 0; i--)
1329         {
1330                 pListGroupNode = GetGroupNode(i);
1331                 SysTryReturnVoidResult(NID_UI_CTRL, pListGroupNode != null, GetLastResult(),
1332                                         "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1333
1334                 if (pListGroupNode->__items.empty() == false)
1335                 {
1336                         pItem = pListGroupNode->__items.back();
1337                         pItem->GetItemIndex(groupIndex, itemIndex);
1338                         break;
1339                 }
1340         }
1341 }
1342
1343 result
1344 _ListViewModel::AddItemToGroup(_IListItemCommon* pItem, int groupIndex)
1345 {
1346         return InsertItemToGroup(pItem, groupIndex, GetItemCountInGroup(groupIndex));
1347 }
1348
1349
1350 result
1351 _ListViewModel::InsertItemToGroup(_IListItemCommon* pItem, int groupIndex, int itemIndex)
1352 {
1353         // check validation of groupIndex
1354         SysTryReturn(NID_UI_CTRL, (groupIndex >= 0 && groupIndex < __countOfAllGroups), E_INVALID_ARG, E_INVALID_ARG,
1355                                 "[E_INVALID_ARG] Wrong group index(%d).", groupIndex);
1356
1357         if (itemIndex < -1 || itemIndex > GetItemCountInGroup(groupIndex))
1358         {
1359                 SysLogException(NID_UI_CTRL, E_INVALID_ARG, "[E_INVALID_ARG] Item index is not valid.");
1360                 return E_INVALID_ARG;
1361         }
1362
1363         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
1364         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
1365                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1366
1367         _IListItemCommon* pTemporaryItem = null;
1368         int temporaryGroupIndex = -1;
1369         int temporaryItemIndex = -1;
1370         int itemCount = pListGroupNode->__items.size();
1371         for (int i = itemCount - 1; i >= 0; i--)
1372         {
1373                 pTemporaryItem = pListGroupNode->__items.at(i);
1374                 if (pTemporaryItem != null)
1375                 {
1376                         pTemporaryItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
1377                         if (temporaryItemIndex >= itemIndex)
1378                         {
1379                                 pTemporaryItem->SetItemIndex(temporaryGroupIndex, ++temporaryItemIndex);
1380                         }
1381                         else
1382                         {
1383                                 break;
1384                         }
1385                 }
1386         }
1387
1388         _LinkedList <int>::_Iterator theIter;
1389         // checked(radio/check) item index
1390         if (pListGroupNode->__usingRadioStyle == true)
1391         {
1392                 //radio item
1393                 if (pListGroupNode->__radioCheckedItemIndex >= itemIndex)
1394                 {
1395                         pListGroupNode->__radioCheckedItemIndex++;
1396                 }
1397         }
1398         else
1399         {
1400                 theIter = pListGroupNode->__checkedItems.begin();
1401                 while (theIter != pListGroupNode->__checkedItems.end())
1402                 {
1403                         if (*theIter >= itemIndex)
1404                         {
1405                                 (*theIter) += 1;
1406                         }
1407
1408                         theIter++;
1409                 }
1410         }
1411
1412         // disabled item index
1413         theIter = pListGroupNode->__disabledItems.begin();
1414         while (theIter != pListGroupNode->__disabledItems.end())
1415         {
1416                 if (*theIter >= itemIndex)
1417                 {
1418                         (*theIter) += 1;
1419                 }
1420
1421                 theIter++;
1422         }
1423
1424         pListGroupNode->__itemCountInGroup++;
1425         __countOfAllItems++;
1426
1427         result r = E_SUCCESS;
1428
1429         if (pItem !=null)
1430         {
1431                 pItem->SetItemIndex(groupIndex, itemIndex);
1432                 r = LoadItemToContainer(groupIndex, itemIndex, *pItem);
1433         }
1434
1435         return r;
1436 }
1437
1438 result
1439 _ListViewModel::SetItem(_IListItemCommon& item, int groupIndex, int itemIndex)
1440 {
1441         // check validation of groupIndex
1442         SysTryReturn(NID_UI_CTRL, (groupIndex >= 0 && groupIndex < __countOfAllGroups), E_INVALID_ARG, E_INVALID_ARG,
1443                                 "[E_INVALID_ARG] Wrong group index(%d).", groupIndex);
1444
1445         if (itemIndex < -1 || itemIndex > GetItemCountInGroup(groupIndex))
1446         {
1447                 SysLogException(NID_UI_CTRL, E_INVALID_ARG, "[E_INVALID_ARG] Item index is not valid.");
1448                 return E_INVALID_ARG;
1449         }
1450
1451         if (IsLoadedItem(groupIndex, itemIndex) == false)
1452         {
1453                 return __pListProviderAdaptor->UnloadItem(&item, groupIndex, itemIndex);
1454         }
1455
1456         _ListViewGroupNode* pListGroupNode = GetGroupNode(groupIndex);
1457         SysTryReturn(NID_UI_CTRL, pListGroupNode != null, GetLastResult(), GetLastResult(),
1458                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1459
1460         item.SetItemIndex(groupIndex, itemIndex);
1461         item.SetChecked(IsItemChecked(groupIndex, itemIndex));
1462         item.SetItemEnabled(IsItemEnabled(groupIndex, itemIndex));
1463
1464         _LinkedList <_IListItemCommon*>::_Iterator theIter = pListGroupNode->__items.begin();
1465
1466         _IListItemCommon* pPreviousItem = null;
1467         int temporaryGroupIndex = -1;
1468         int temporaryItemIndex = -1;
1469         while (theIter != pListGroupNode->__items.end())
1470         {
1471                 pPreviousItem = *theIter;
1472                 pPreviousItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
1473
1474                 if (temporaryItemIndex == itemIndex)
1475                 {
1476                         *theIter = &item;
1477                         break;
1478                 }
1479                 else if (temporaryItemIndex > itemIndex)
1480                 {
1481                         return __pListProviderAdaptor->UnloadItem(&item, groupIndex, itemIndex);
1482                 }
1483
1484                 theIter++;
1485         }
1486
1487         return __pListProviderAdaptor->UnloadItem(pPreviousItem, groupIndex, itemIndex);
1488 }
1489
1490 // origin & destination item must be loaded
1491 result
1492 _ListViewModel::MoveItem(int originGroupIndex, int originItemIndex, int destinationGroupIndex, int destinationItemIndex)
1493 {
1494         if (IsValidItem(originGroupIndex, originItemIndex) == false
1495                 || IsValidItem(destinationGroupIndex, destinationItemIndex - 1) == false)
1496         {
1497                 SysLogException(NID_UI_CTRL, E_INVALID_ARG, "[E_INVALID_ARG] Item index is not valid.");
1498                 return E_SYSTEM;
1499         }
1500
1501         _ListViewGroupNode* pOriginGroupNode = GetGroupNode(originGroupIndex);
1502         SysTryReturn(NID_UI_CTRL, pOriginGroupNode != null, GetLastResult(), GetLastResult(),
1503                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1504
1505         _ListViewGroupNode* pDestinationGroupNode = GetGroupNode(destinationGroupIndex);
1506         SysTryReturn(NID_UI_CTRL, pDestinationGroupNode != null, GetLastResult(), GetLastResult(),
1507                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1508
1509         _IListItemCommon* pItem = GetItemFromContainer(originGroupIndex, originItemIndex);
1510         SysTryReturn(NID_UI_CTRL, pItem != null, GetLastResult(), GetLastResult(),
1511                                  "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1512
1513         _IListItemCommon* pTemporaryItem = null;
1514         int temporaryGroupIndex = -1;
1515         int temporaryItemIndex = -1;
1516         int indexCount = 0;
1517         bool isFound = false;
1518
1519         if (originGroupIndex != destinationGroupIndex)  // different group
1520         {
1521                 pOriginGroupNode->__items.remove(pItem);
1522
1523                 _LinkedList <_IListItemCommon*>::_Iterator theIter = pOriginGroupNode->__items.begin();
1524                 while (theIter != pOriginGroupNode->__items.end())
1525                 {
1526                         pTemporaryItem = *theIter;
1527                         pTemporaryItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
1528
1529                         if (temporaryItemIndex > originItemIndex)
1530                         {
1531                                 pTemporaryItem->SetItemIndex(temporaryGroupIndex, temporaryItemIndex - 1);
1532                         }
1533
1534                         theIter++;
1535                 }
1536
1537                 pItem->SetItemIndex(destinationGroupIndex, destinationItemIndex);
1538
1539                 _LinkedList <_IListItemCommon*>::_Iterator destinationIter = pDestinationGroupNode->__items.begin();
1540                 while (destinationIter != pDestinationGroupNode->__items.end())
1541                 {
1542                         pTemporaryItem = *destinationIter;
1543                         pTemporaryItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
1544
1545                         if (temporaryItemIndex >= destinationItemIndex)
1546                         {
1547                                 pTemporaryItem->SetItemIndex(temporaryGroupIndex, temporaryItemIndex + 1);
1548
1549                                 if (temporaryItemIndex == destinationItemIndex)
1550                                 {
1551                                         pDestinationGroupNode->__items.insert(destinationIter, pItem);
1552                                         isFound = true;
1553                                 }
1554                         }
1555
1556                         destinationIter++;
1557                 }
1558
1559                 if (isFound == false)
1560                 {
1561                         pDestinationGroupNode->__items.push_back(pItem);
1562                 }
1563
1564                 // remove checked(radio/check) & disabled item index
1565                 MoveCheckedAndDisabledItemIndex(pOriginGroupNode, originItemIndex, -1, pItem->IsChecked(), pItem->IsItemEnabled());
1566
1567                 // insert checked(radio/check) & disabled item index
1568                 MoveCheckedAndDisabledItemIndex(pDestinationGroupNode, -1, destinationItemIndex, pItem->IsChecked(), pItem->IsItemEnabled());
1569
1570                 pOriginGroupNode->__itemCountInGroup--;
1571                 pDestinationGroupNode->__itemCountInGroup++;
1572         }
1573         else    // same group
1574         {
1575                 pOriginGroupNode->__items.remove(pItem);
1576
1577                 _LinkedList <_IListItemCommon*>::_Iterator theIter = pOriginGroupNode->__items.begin();
1578                 while (theIter != pOriginGroupNode->__items.end())
1579                 {
1580                         pTemporaryItem = *theIter;
1581                         pTemporaryItem->GetItemIndex(temporaryGroupIndex, temporaryItemIndex);
1582
1583                         if (temporaryItemIndex < originItemIndex && temporaryItemIndex >= destinationItemIndex)
1584                         {
1585                                 pTemporaryItem->SetItemIndex(temporaryGroupIndex, temporaryItemIndex + 1);
1586                         }
1587                         else if (temporaryItemIndex > originItemIndex && temporaryItemIndex <= destinationItemIndex)
1588                         {
1589                                 pTemporaryItem->SetItemIndex(temporaryGroupIndex, temporaryItemIndex - 1);
1590
1591                                 if (temporaryItemIndex == destinationItemIndex)
1592                                 {
1593                                         indexCount++;
1594                                 }
1595                         }
1596                         else if (temporaryItemIndex > originItemIndex && temporaryItemIndex > destinationItemIndex)
1597                         {
1598                                 break;
1599                         }
1600
1601                         if (temporaryItemIndex < destinationItemIndex)
1602                         {
1603                                 indexCount++;
1604                         }
1605
1606                         theIter++;
1607                 }
1608
1609                 if (indexCount < 0)
1610                 {
1611                         indexCount = 0;
1612                 }
1613
1614                 pItem->SetItemIndex(destinationGroupIndex, destinationItemIndex);
1615                 pOriginGroupNode->__items.insert(pOriginGroupNode->__items.begin() + indexCount, pItem);
1616
1617                 // move checked(radio/check) & disabled item index
1618                 MoveCheckedAndDisabledItemIndex(pOriginGroupNode, originItemIndex, destinationItemIndex, pItem->IsChecked(), pItem->IsItemEnabled());
1619         }
1620
1621         return E_SUCCESS;
1622 }
1623
1624 // insert mode : originItemIndex == -1
1625 // remove mode : destinationItemIndex == -1
1626 void
1627 _ListViewModel::MoveCheckedAndDisabledItemIndex(_ListViewGroupNode* pListGroupNode, int originItemIndex, int destinationItemIndex, bool checked, bool enabled)
1628 {
1629         int indexCount = 0;
1630         int temporaryDestinationIndex = destinationItemIndex;
1631         if (destinationItemIndex == -1)
1632         {
1633                 temporaryDestinationIndex = pListGroupNode->__itemCountInGroup;
1634         }
1635
1636         // move checked(radio/check) item index
1637         if (pListGroupNode->__usingRadioStyle)
1638         {
1639                 //radio style
1640                 if (checked == true || (pListGroupNode->__radioCheckedItemIndex == originItemIndex && originItemIndex != -1))   // for insert mode
1641                 {
1642                         pListGroupNode->__radioCheckedItemIndex = destinationItemIndex;
1643                 }
1644                 else if (pListGroupNode->__radioCheckedItemIndex < originItemIndex &&
1645                                  pListGroupNode->__radioCheckedItemIndex >= temporaryDestinationIndex)
1646                 {
1647                         pListGroupNode->__radioCheckedItemIndex++;
1648                 }
1649                 else if (originItemIndex != -1 &&
1650                                  pListGroupNode->__radioCheckedItemIndex > originItemIndex &&
1651                                  pListGroupNode->__radioCheckedItemIndex < temporaryDestinationIndex)
1652                 {
1653                         pListGroupNode->__radioCheckedItemIndex--;
1654                 }
1655         }
1656         else
1657         {
1658                 //checked style
1659                 int checkedItemIndex = -1;
1660                 _LinkedList <int>::_Iterator theIter = pListGroupNode->__checkedItems.begin();
1661
1662                 while (theIter != pListGroupNode->__checkedItems.end())
1663                 {
1664                         checkedItemIndex = (int)(*theIter);
1665                         if (originItemIndex == -1)      // insert mode
1666                         {
1667                                 if (checkedItemIndex >= temporaryDestinationIndex)
1668                                 {
1669                                         *theIter = checkedItemIndex + 1;
1670                                 }
1671                                 else
1672                                 {
1673                                         indexCount++;
1674                                 }
1675                         }
1676                         else
1677                         {
1678                                 if (checkedItemIndex < originItemIndex && checkedItemIndex >= temporaryDestinationIndex)
1679                                 {
1680                                         *theIter = checkedItemIndex + 1;
1681                                 }
1682                                 else if (checkedItemIndex > originItemIndex && checkedItemIndex < temporaryDestinationIndex)
1683                                 {
1684                                         *theIter = checkedItemIndex - 1;
1685                                 }
1686                                 else if (checkedItemIndex == originItemIndex)
1687                                 {
1688                                         pListGroupNode->__checkedItems.erase(theIter);
1689                                         continue;
1690                                 }
1691                                 else if (checkedItemIndex > originItemIndex && checkedItemIndex > temporaryDestinationIndex)
1692                                 {
1693                                         break;
1694                                 }
1695
1696                                 if (checkedItemIndex <= temporaryDestinationIndex && checkedItemIndex != originItemIndex)
1697                                 {
1698                                         indexCount++;
1699                                 }
1700                         }
1701
1702                         theIter++;
1703                 }
1704
1705                 if (destinationItemIndex != -1 && checked == true)
1706                 {
1707                         pListGroupNode->__checkedItems.insert(pListGroupNode->__checkedItems.begin()
1708                                                                                                   + indexCount, destinationItemIndex);
1709                 }
1710         }
1711
1712         indexCount = 0;
1713
1714         // move disabled
1715         int disabledItemIndex = -1;
1716         _LinkedList <int>::_Iterator theIter = pListGroupNode->__disabledItems.begin();
1717
1718         while (theIter != pListGroupNode->__disabledItems.end())
1719         {
1720                 disabledItemIndex = (int)(*theIter);
1721                 if (originItemIndex == -1)      // insert mode
1722                 {
1723                         if (disabledItemIndex >= temporaryDestinationIndex)
1724                         {
1725                                 *theIter = disabledItemIndex + 1;
1726                         }
1727                         else
1728                         {
1729                                 indexCount++;
1730                         }
1731                 }
1732                 else
1733                 {
1734                         if (disabledItemIndex < originItemIndex && disabledItemIndex >= temporaryDestinationIndex)
1735                         {
1736                                 *theIter = disabledItemIndex + 1;
1737                         }
1738                         else if (disabledItemIndex > originItemIndex && disabledItemIndex < temporaryDestinationIndex)
1739                         {
1740                                 *theIter = disabledItemIndex - 1;
1741                         }
1742                         else if (disabledItemIndex == originItemIndex)
1743                         {
1744                                 pListGroupNode->__disabledItems.erase(theIter);
1745                                 continue;
1746                         }
1747                         else if (disabledItemIndex > originItemIndex && disabledItemIndex > temporaryDestinationIndex)
1748                         {
1749                                 break;
1750                         }
1751
1752                         if (disabledItemIndex <= temporaryDestinationIndex && disabledItemIndex != originItemIndex)
1753                         {
1754                                 indexCount++;
1755                         }
1756                 }
1757
1758                 theIter++;
1759         }
1760
1761         if (destinationItemIndex != -1 && enabled == false)
1762         {
1763                 pListGroupNode->__disabledItems.insert(pListGroupNode->__disabledItems.begin()
1764                                                                                           + indexCount, destinationItemIndex);
1765         }
1766 }
1767
1768 _ListViewGroupNode*
1769 _ListViewModel::GetGroupNode(int groupIndex) const
1770 {
1771         if (__groupNodes.empty())
1772         {
1773                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] GroupNode is Empty.");
1774                 return null;
1775         }
1776
1777         _ListViewGroupNode* pListGroupNode = __groupNodes.at(groupIndex);
1778         if (pListGroupNode == null)
1779         {
1780                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Failed to get _ListViewGroupNode.");
1781         }
1782
1783         return pListGroupNode;
1784 }
1785
1786 }}} // Tizen::Ui::Controls
1787