Listview T6

Dimitrie O. Paun dpaun at rogers.com
Fri Oct 18 18:13:27 CDT 2002


Again, I am interested in *all* selection problems, glitches, etc.

ChangeLog
  More traces to help us make sense of the output
  Faster, cleaner ranges_{add,del}.

--- dlls/comctl32/listview.c.T5	Fri Oct 18 18:00:47 2002
+++ dlls/comctl32/listview.c	Fri Oct 18 19:10:47 2002
@@ -926,6 +926,7 @@
 
     if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;
 
+    TRACE("(lprc=%s)\n", debugrect(lprc));
     OffsetRect(&frame, -Origin.x, -Origin.y);
 
     if (uView == LVS_ICON || uView == LVS_SMALLICON)
@@ -939,6 +940,7 @@
 	}
 	if (!(i->ranges = ranges_create(50))) return FALSE;
 	/* to do better here, we need to have PosX, and PosY sorted */
+	TRACE("building icon ranges:\n");
 	for (nItem = 0; nItem < infoPtr->nItemCount; nItem++)
 	{
             rcItem.left = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
@@ -986,6 +988,7 @@
 	if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE;
 
 	if (!(i->ranges = ranges_create(nLastCol - nFirstCol + 1))) return FALSE;
+	TRACE("building list ranges:\n");
 	for (nCol = nFirstCol; nCol <= nLastCol; nCol++)
 	{
 	    item_range.lower = nCol * nPerCol + nFirstRow;
@@ -1019,6 +1022,7 @@
     
     /* if we can't deal with the region, we'll just go with the simple range */
     if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return TRUE;
+    TRACE("building visible range:\n");
     if (!i->ranges)
     {
 	if (!(i->ranges = ranges_create(50))) return TRUE;
@@ -1042,6 +1046,7 @@
 	    ranges_delitem(i->ranges, i->nItem);
     }
     /* the iterator should restart on the next iterator_next */
+    TRACE("done\n");
     
     return TRUE;
 }
@@ -2232,7 +2237,7 @@
     assert (ranges);
     assert (ranges->hdpa->nItemCount >= 0);
     if (ranges->hdpa->nItemCount == 0) return;
-    TRACE("Checking %s:\n", desc);
+    TRACE("*** Checking %s ***\n", desc);
     ranges_dump(ranges);
     assert ((prev = (RANGE *)DPA_GetPtr(ranges->hdpa, 0))->lower >= 0);
     /* assert (((RANGE *)DPA_GetPtr(ranges->hdpa, ranges->hdpa->nItemCount - 1))->upper <= nUpper); */
@@ -2242,6 +2247,7 @@
 	assert (prev->upper <= curr->lower);
 	prev = curr;
     }
+    TRACE("--- Done checking---\n");
 }
 
 static RANGES ranges_create(int count)
@@ -2370,7 +2376,7 @@
     /* try find overlapping regions first */
     srchrgn.lower = range.lower - 1;
     srchrgn.upper = range.upper + 1;
-    index = DPA_Search(ranges->hdpa, &srchrgn, 0, ranges_cmp, 0, 0);
+    index = DPA_Search(ranges->hdpa, &srchrgn, 0, ranges_cmp, 0, DPAS_SORTED);
    
     if (index == -1)
     {
@@ -2444,64 +2450,65 @@
 
 static BOOL ranges_del(RANGES ranges, RANGE range)
 {
-    RANGE remrgn, tmprgn, *chkrgn;
-    BOOL done = FALSE;
+    RANGE *chkrgn;
     INT index;
 
     TRACE("(%s)\n", debugrange(&range));
     ranges_check(ranges, "before del");
     if (!ranges) goto fail;
     
-    remrgn = range;
-    do 
+    /* we don't use DPAS_SORTED here, since we need *
+     * to find the first overlapping range          */
+    index = DPA_Search(ranges->hdpa, &range, 0, ranges_cmp, 0, 0);
+    while(index != -1) 
     {
-	index = DPA_Search(ranges->hdpa, &remrgn, 0, ranges_cmp, 0, 0);
-	if (index == -1) break;
-
 	chkrgn = DPA_GetPtr(ranges->hdpa, index);
 	if (!chkrgn) goto fail;
 	
         TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); 
 
 	/* case 1: Same range */
-	if ( (chkrgn->upper == remrgn.upper) &&
-	     (chkrgn->lower == remrgn.lower) )
+	if ( (chkrgn->upper == range.upper) &&
+	     (chkrgn->lower == range.lower) )
 	{
 	    DPA_DeletePtr(ranges->hdpa, index);
-	    done = TRUE;
+	    break;
 	}
 	/* case 2: engulf */
-	else if ( (chkrgn->upper <= remrgn.upper) &&
-		  (chkrgn->lower >= remrgn.lower) ) 
+	else if ( (chkrgn->upper <= range.upper) &&
+		  (chkrgn->lower >= range.lower) ) 
 	{
 	    DPA_DeletePtr(ranges->hdpa, index);
 	}
 	/* case 3: overlap upper */
-	else if ( (chkrgn->upper <= remrgn.upper) &&
-		  (chkrgn->lower < remrgn.lower) )
+	else if ( (chkrgn->upper <= range.upper) &&
+		  (chkrgn->lower < range.lower) )
 	{
-	    chkrgn->upper = remrgn.lower;
+	    chkrgn->upper = range.lower;
 	}
 	/* case 4: overlap lower */
-	else if ( (chkrgn->upper > remrgn.upper) &&
-		  (chkrgn->lower >= remrgn.lower) )
+	else if ( (chkrgn->upper > range.upper) &&
+		  (chkrgn->lower >= range.lower) )
 	{
-	    chkrgn->lower = remrgn.upper;
+	    chkrgn->lower = range.upper;
+	    break;
 	}
 	/* case 5: fully internal */
 	else
 	{
-	    RANGE *newrgn = (RANGE *)COMCTL32_Alloc(sizeof(RANGE));
-	    if (!newrgn) goto fail;
-	    tmprgn = *chkrgn;
+	    RANGE tmprgn = *chkrgn, *newrgn;
+
+	    if (!(newrgn = (RANGE *)COMCTL32_Alloc(sizeof(RANGE)))) goto fail;
 	    newrgn->lower = chkrgn->lower;
-	    newrgn->upper = remrgn.lower;
-	    chkrgn->lower = remrgn.upper;
+	    newrgn->upper = range.lower;
+	    chkrgn->lower = range.upper;
 	    DPA_InsertPtr(ranges->hdpa, index, newrgn);
 	    chkrgn = &tmprgn;
+	    break;
 	}
+
+	index = DPA_Search(ranges->hdpa, &range, index, ranges_cmp, 0, 0);
     }
-    while(!done);
 
     ranges_check(ranges, "after del");
     return TRUE;




More information about the wine-patches mailing list