Better encapsulation of the ranges concept.
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 5639f77..d89d1ef 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -107,12 +107,17 @@
INT upper;
} RANGE;
+typedef struct tagRANGES
+{
+ HDPA hdpa;
+} *RANGES;
+
typedef struct tagITERATOR
{
INT nItem;
INT nSpecial;
RANGE range;
- HDPA ranges;
+ RANGES ranges;
INT index;
} ITERATOR;
@@ -131,7 +136,7 @@
BOOL bRButtonDown;
INT nItemHeight;
INT nItemWidth;
- HDPA hdpaSelectionRanges;
+ RANGES selectionRanges;
INT nSelectionMark;
BOOL bRemovingAllSelections;
INT nHotItem;
@@ -681,9 +686,11 @@
/******** Item iterator functions **********************************/
-static BOOL ranges_add(HDPA ranges, RANGE range);
-static BOOL ranges_del(HDPA ranges, RANGE range);
-static void ranges_dump(HDPA ranges);
+static RANGES ranges_create(int count);
+static void ranges_destroy(RANGES ranges);
+static BOOL ranges_add(RANGES ranges, RANGE range);
+static BOOL ranges_del(RANGES ranges, RANGE range);
+static void ranges_dump(RANGES ranges);
/***
* ITERATOR DOCUMENTATION
@@ -767,8 +774,8 @@
pickarange:
if (i->ranges)
{
- if (i->index < i->ranges->nItemCount)
- i->range = *(RANGE*)DPA_GetPtr(i->ranges, i->index++);
+ if (i->index < i->ranges->hdpa->nItemCount)
+ i->range = *(RANGE*)DPA_GetPtr(i->ranges->hdpa, i->index++);
else goto end;
}
else if (i->nItem > i->range.upper) goto end;
@@ -793,7 +800,7 @@
if (i->nItem == -1)
{
start = TRUE;
- if (i->ranges) i->index = i->ranges->nItemCount;
+ if (i->ranges) i->index = i->ranges->hdpa->nItemCount;
goto pickarange;
}
if (i->nItem == i->nSpecial)
@@ -811,7 +818,7 @@
if (i->ranges)
{
if (i->index > 0)
- i->range = *(RANGE*)DPA_GetPtr(i->ranges, --i->index);
+ i->range = *(RANGE*)DPA_GetPtr(i->ranges->hdpa, --i->index);
else goto end;
}
else if (!start && i->nItem < i->range.lower) goto end;
@@ -828,8 +835,8 @@
if (!i->ranges) return i->range;
- range.lower = (*(RANGE*)DPA_GetPtr(i->ranges, 0)).lower;
- range.upper = (*(RANGE*)DPA_GetPtr(i->ranges, i->ranges->nItemCount - 1)).upper;
+ range.lower = (*(RANGE*)DPA_GetPtr(i->ranges->hdpa, 0)).lower;
+ range.upper = (*(RANGE*)DPA_GetPtr(i->ranges->hdpa, i->ranges->hdpa->nItemCount - 1)).upper;
return range;
}
@@ -838,7 +845,7 @@
*/
static inline void iterator_destroy(ITERATOR* i)
{
- if (i->ranges) DPA_Destroy(i->ranges);
+ if (i->ranges) ranges_destroy(i->ranges);
}
/***
@@ -876,7 +883,7 @@
if (LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcItem) && IntersectRect(&rcTemp, &rcItem, lprc))
i->nSpecial = infoPtr->nFocusedItem;
}
- if (!(i->ranges = DPA_Create(50))) return FALSE;
+ if (!(i->ranges = ranges_create(50))) return FALSE;
/* to do better here, we need to have PosX, and PosY sorted */
for (nItem = 0; nItem < infoPtr->nItemCount; nItem++)
{
@@ -923,7 +930,7 @@
if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE;
- if (!(i->ranges = DPA_Create(nLastCol - nFirstCol + 1))) return FALSE;
+ if (!(i->ranges = ranges_create(nLastCol - nFirstCol + 1))) return FALSE;
for (nCol = nFirstCol; nCol <= nLastCol; nCol++)
{
item_range.lower = nCol * nPerCol + nFirstRow;
@@ -959,10 +966,10 @@
if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return TRUE;
if (!i->ranges)
{
- if (!(i->ranges = DPA_Create(50))) return TRUE;
+ if (!(i->ranges = ranges_create(50))) return TRUE;
if (!ranges_add(i->ranges, i->range))
{
- DPA_Destroy(i->ranges);
+ ranges_destroy(i->ranges);
i->ranges = 0;
return TRUE;
}
@@ -2124,7 +2131,7 @@
static void LISTVIEW_PrintSelectionRanges(LISTVIEW_INFO *infoPtr)
{
ERR("Selections are:\n");
- ranges_dump(infoPtr->hdpaSelectionRanges);
+ ranges_dump(infoPtr->selectionRanges);
}
#endif
@@ -2151,27 +2158,58 @@
return 0;
}
-static void ranges_dump(HDPA ranges)
+static RANGES ranges_create(int count)
+{
+ RANGES ranges = (RANGES)COMCTL32_Alloc(sizeof(struct tagRANGES));
+ if (!ranges) return NULL;
+ ranges->hdpa = DPA_Create(count);
+ if (ranges->hdpa) return ranges;
+ COMCTL32_Free(ranges);
+ return NULL;
+}
+
+static void ranges_destroy(RANGES ranges)
+{
+ if (!ranges) return;
+ DPA_Destroy(ranges->hdpa);
+ ranges->hdpa = NULL;
+ COMCTL32_Free(ranges);
+}
+
+static void ranges_dump(RANGES ranges)
{
INT i;
- for (i = 0; i < ranges->nItemCount; i++)
+ for (i = 0; i < ranges->hdpa->nItemCount; i++)
{
- RANGE *selection = DPA_GetPtr(ranges, i);
+ RANGE *selection = DPA_GetPtr(ranges->hdpa, i);
TRACE(" [%d - %d]\n", selection->lower, selection->upper);
}
}
-static inline BOOL ranges_contain(HDPA ranges, INT nItem)
+static inline BOOL ranges_contain(RANGES ranges, INT nItem)
{
RANGE srchrng = { nItem, nItem };
TRACE("(nItem=%d)\n", nItem);
if (TRACE_ON(listview)) ranges_dump(ranges);
- return DPA_Search(ranges, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED) != -1;
+ return DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED) != -1;
}
-static BOOL ranges_shift(HDPA ranges, INT nItem, INT delta, INT nUpper)
+static INT ranges_itemcount(RANGES ranges)
+{
+ INT i, count = 0;
+
+ for (i = 0; i < ranges->hdpa->nItemCount; i++)
+ {
+ RANGE *sel = DPA_GetPtr(ranges->hdpa, i);
+ count += sel->upper - sel->lower + 1;
+ }
+
+ return count;
+}
+
+static BOOL ranges_shift(RANGES ranges, INT nItem, INT delta, INT nUpper)
{
RANGE srchrng, *chkrng;
INT index;
@@ -2179,12 +2217,12 @@
srchrng.upper = nItem;
srchrng.lower = nItem;
- index = DPA_Search(ranges, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER);
+ index = DPA_Search(ranges->hdpa, &srchrng, 0, ranges_cmp, 0, DPAS_SORTED | DPAS_INSERTAFTER);
if (index == -1) return TRUE;
- for (;index < ranges->nItemCount; index++)
+ for (;index < ranges->hdpa->nItemCount; index++)
{
- chkrng = DPA_GetPtr(ranges, index);
+ chkrng = DPA_GetPtr(ranges->hdpa, index);
if (chkrng->lower >= nItem)
chkrng->lower = max(min(chkrng->lower + delta, nUpper - 1), 0);
if (chkrng->upper >= nItem)
@@ -2193,7 +2231,7 @@
return TRUE;
}
-static BOOL ranges_add(HDPA ranges, RANGE range)
+static BOOL ranges_add(RANGES ranges, RANGE range)
{
RANGE srchrgn;
INT index;
@@ -2204,7 +2242,7 @@
/* try find overlapping regions first */
srchrgn.lower = range.lower - 1;
srchrgn.upper = range.upper + 1;
- index = DPA_Search(ranges, &srchrgn, 0, ranges_cmp, 0, 0);
+ index = DPA_Search(ranges->hdpa, &srchrgn, 0, ranges_cmp, 0, 0);
if (index == -1)
{
@@ -2218,18 +2256,18 @@
*newrgn = range;
/* figure out where to insert it */
- index = DPA_Search(ranges, newrgn, 0, ranges_cmp, 0, DPAS_INSERTAFTER);
+ index = DPA_Search(ranges->hdpa, newrgn, 0, ranges_cmp, 0, DPAS_INSERTAFTER);
if (index == -1) index = 0;
/* and get it over with */
- DPA_InsertPtr(ranges, index, newrgn);
+ DPA_InsertPtr(ranges->hdpa, index, newrgn);
}
else
{
RANGE *chkrgn, *mrgrgn;
INT fromindex, mergeindex;
- chkrgn = DPA_GetPtr(ranges, index);
+ chkrgn = DPA_GetPtr(ranges->hdpa, index);
if (!chkrgn) return FALSE;
TRACE("Merge with index %i (%d - %d)\n",
index, chkrgn->lower, chkrgn->upper);
@@ -2247,7 +2285,7 @@
do
{
- mergeindex = DPA_Search(ranges, &srchrgn, fromindex, ranges_cmp, 0, 0);
+ mergeindex = DPA_Search(ranges->hdpa, &srchrgn, fromindex, ranges_cmp, 0, 0);
if (mergeindex == -1) break;
if (mergeindex == index)
{
@@ -2257,13 +2295,13 @@
TRACE("Merge with index %i\n", mergeindex);
- mrgrgn = DPA_GetPtr(ranges, mergeindex);
+ mrgrgn = DPA_GetPtr(ranges->hdpa, mergeindex);
if (!mrgrgn) return FALSE;
chkrgn->lower = min(chkrgn->lower, mrgrgn->lower);
chkrgn->upper = max(chkrgn->upper, mrgrgn->upper);
COMCTL32_Free(mrgrgn);
- DPA_DeletePtr(ranges, mergeindex);
+ DPA_DeletePtr(ranges->hdpa, mergeindex);
if (mergeindex < index) index --;
} while(1);
}
@@ -2272,7 +2310,7 @@
return TRUE;
}
-static BOOL ranges_del(HDPA ranges, RANGE range)
+static BOOL ranges_del(RANGES ranges, RANGE range)
{
RANGE remrgn, tmprgn, *chkrgn;
BOOL done = FALSE;
@@ -2283,10 +2321,10 @@
remrgn = range;
do
{
- index = DPA_Search(ranges, &remrgn, 0, ranges_cmp, 0, 0);
+ index = DPA_Search(ranges->hdpa, &remrgn, 0, ranges_cmp, 0, 0);
if (index == -1) return TRUE;
- chkrgn = DPA_GetPtr(ranges, index);
+ chkrgn = DPA_GetPtr(ranges->hdpa, index);
if (!chkrgn) return FALSE;
TRACE("Matches range index %i (%d - %d)\n",
@@ -2296,14 +2334,14 @@
if ( (chkrgn->upper == remrgn.upper) &&
(chkrgn->lower == remrgn.lower) )
{
- DPA_DeletePtr(ranges, index);
+ DPA_DeletePtr(ranges->hdpa, index);
done = TRUE;
}
/* case 2: engulf */
else if ( (chkrgn->upper <= remrgn.upper) &&
(chkrgn->lower >= remrgn.lower) )
{
- DPA_DeletePtr(ranges, index);
+ DPA_DeletePtr(ranges->hdpa, index);
}
/* case 3: overlap upper */
else if ( (chkrgn->upper <= remrgn.upper) &&
@@ -2326,7 +2364,7 @@
newrgn->lower = chkrgn->lower;
newrgn->upper = remrgn.lower - 1;
chkrgn->lower = remrgn.upper + 1;
- DPA_InsertPtr(ranges, index, newrgn);
+ DPA_InsertPtr(ranges->hdpa, index, newrgn);
chkrgn = &tmprgn;
}
}
@@ -2364,7 +2402,7 @@
lvItem.stateMask = LVIS_SELECTED;
/* need to clone the DPA because callbacks can change it */
- clone = DPA_Clone(infoPtr->hdpaSelectionRanges, NULL);
+ clone = DPA_Clone(infoPtr->selectionRanges->hdpa, NULL);
for ( pos = 0; (sel = DPA_GetPtr(clone, pos)); pos++ )
{
for(i = sel->lower; i <= sel->upper; i++)
@@ -2392,7 +2430,7 @@
*/
static INT LISTVIEW_GetSelectedCount(LISTVIEW_INFO *infoPtr)
{
- INT i, nSelectedCount = 0;
+ INT nSelectedCount = 0;
if (infoPtr->uCallbackMask & LVIS_SELECTED)
{
@@ -2404,13 +2442,7 @@
}
}
else
- {
- for (i = 0; i < infoPtr->hdpaSelectionRanges->nItemCount; i++)
- {
- RANGE *sel = DPA_GetPtr(infoPtr->hdpaSelectionRanges, i);
- nSelectedCount += sel->upper - sel->lower + 1;
- }
- }
+ nSelectedCount = ranges_itemcount(infoPtr->selectionRanges);
TRACE("nSelectedCount=%d\n", nSelectedCount);
return nSelectedCount;
@@ -2470,7 +2502,7 @@
TRACE("Shifting %iu, %i steps\n", nItem, direction);
- ranges_shift(infoPtr->hdpaSelectionRanges, nItem, direction, infoPtr->nItemCount);
+ ranges_shift(infoPtr->selectionRanges, nItem, direction, infoPtr->nItemCount);
assert(abs(direction) == 1);
@@ -2792,10 +2824,10 @@
if (lpLVItem->state & LVIS_SELECTED)
{
if (lStyle & LVS_SINGLESEL) LISTVIEW_RemoveAllSelections(infoPtr, lpLVItem->iItem);
- ranges_add(infoPtr->hdpaSelectionRanges, range);
+ ranges_add(infoPtr->selectionRanges, range);
}
else
- ranges_del(infoPtr->hdpaSelectionRanges, range);
+ ranges_del(infoPtr->selectionRanges, range);
}
/* notify the parent now that things have changed */
@@ -2895,10 +2927,10 @@
if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED)
{
if (lStyle & LVS_SINGLESEL) LISTVIEW_RemoveAllSelections(infoPtr, lpLVItem->iItem);
- ranges_add(infoPtr->hdpaSelectionRanges, range);
+ ranges_add(infoPtr->selectionRanges, range);
}
else if (lpLVItem->stateMask & LVIS_SELECTED)
- ranges_del(infoPtr->hdpaSelectionRanges, range);
+ ranges_del(infoPtr->selectionRanges, range);
/* if we are asked to change focus, and we manage it, do it */
if (lpLVItem->state & lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED)
@@ -4640,7 +4672,7 @@
if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED )
{
lpLVItem->state &= ~LVIS_SELECTED;
- if (ranges_contain(infoPtr->hdpaSelectionRanges, lpLVItem->iItem))
+ if (ranges_contain(infoPtr->selectionRanges, lpLVItem->iItem))
lpLVItem->state |= LVIS_SELECTED;
}
@@ -4749,7 +4781,7 @@
if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED )
{
lpLVItem->state &= ~LVIS_SELECTED;
- if (ranges_contain(infoPtr->hdpaSelectionRanges, lpLVItem->iItem))
+ if (ranges_contain(infoPtr->selectionRanges, lpLVItem->iItem))
lpLVItem->state |= LVIS_SELECTED;
}
}
@@ -6924,7 +6956,7 @@
infoPtr->hdpaPosY = DPA_Create(10);
/* allocate memory for the selection ranges */
- infoPtr->hdpaSelectionRanges = DPA_Create(10);
+ infoPtr->selectionRanges = ranges_create(10);
/* initialize size of items */
infoPtr->nItemWidth = LISTVIEW_CalculateMaxWidth(infoPtr);
@@ -7543,7 +7575,7 @@
/* destroy data structure */
DPA_Destroy(infoPtr->hdpaItems);
- DPA_Destroy(infoPtr->hdpaSelectionRanges);
+ ranges_destroy(infoPtr->selectionRanges);
/* destroy image lists */
if (!(lStyle & LVS_SHAREIMAGELISTS))