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