Rewrite DeleteItemT: cleaner, a lot faster.

Number of bug were fixed.
The minimum possible is redrawn.
This commit is contained in:
Dimitrie O. Paun 2002-10-21 19:43:37 +00:00 committed by Alexandre Julliard
parent c859242ac8
commit f18e271bff
1 changed files with 80 additions and 58 deletions

View File

@ -3981,79 +3981,101 @@ static BOOL LISTVIEW_DeleteColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
*/ */
static BOOL LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem) static BOOL LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem)
{ {
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
NMLISTVIEW nmlv; INT nPerCol, nItemCol, nItemRow;
BOOL bResult = FALSE; NMLISTVIEW nmlv;
HDPA hdpaSubItems; LVITEMW item;
LISTVIEW_ITEM *lpItem; BOOL is_icon;
LISTVIEW_SUBITEM *lpSubItem; RECT rcScroll;
LVITEMW item; POINT Origin;
INT i;
TRACE("(nItem=%d)\n", nItem); TRACE("(nItem=%d)\n", nItem);
/* remove selection, and focus */ if (nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE;
item.state = 0;
item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; /* remove selection, and focus */
LISTVIEW_SetItemState(infoPtr, nItem, &item); item.state = 0;
item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
LISTVIEW_SetItemState(infoPtr, nItem, &item);
/* send LVN_DELETEITEM notification. */ /* send LVN_DELETEITEM notification. */
ZeroMemory(&nmlv, sizeof (NMLISTVIEW)); ZeroMemory(&nmlv, sizeof (NMLISTVIEW));
nmlv.iItem = nItem; nmlv.iItem = nItem;
notify_listview(infoPtr, LVN_DELETEITEM, &nmlv); notify_listview(infoPtr, LVN_DELETEITEM, &nmlv);
if (infoPtr->dwStyle & LVS_OWNERDATA) if (!(infoPtr->dwStyle & LVS_OWNERDATA))
{
infoPtr->nItemCount--;
LISTVIEW_InvalidateList(infoPtr); /*FIXME: optimize */
return TRUE;
}
if ((nItem >= 0) && (nItem < infoPtr->nItemCount))
{
/* initialize memory */
ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
hdpaSubItems = (HDPA)DPA_DeletePtr(infoPtr->hdpaItems, nItem);
if (hdpaSubItems != NULL)
{ {
infoPtr->nItemCount--; HDPA hdpaSubItems;
for (i = 1; i < hdpaSubItems->nItemCount; i++) ITEMHDR *hdrItem;
{ INT i;
lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
/* free item string */
if (is_textW(lpSubItem->hdr.pszText))
COMCTL32_Free(lpSubItem->hdr.pszText);
/* free item */ hdpaSubItems = (HDPA)DPA_DeletePtr(infoPtr->hdpaItems, nItem);
COMCTL32_Free(lpSubItem); for (i = 0; i < hdpaSubItems->nItemCount; i++)
} {
hdrItem = (ITEMHDR *)DPA_GetPtr(hdpaSubItems, i);
if (is_textW(hdrItem->pszText)) COMCTL32_Free(hdrItem->pszText);
COMCTL32_Free(hdrItem);
}
DPA_Destroy(hdpaSubItems);
}
is_icon = (uView == LVS_SMALLICON || uView == LVS_ICON);
if (is_icon)
{
RECT rcBox;
lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0); LISTVIEW_GetItemBox(infoPtr, nItem, &rcBox);
/* free item string */ DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
if (is_textW(lpItem->hdr.pszText)) DPA_DeletePtr(infoPtr->hdpaPosY, nItem);
COMCTL32_Free(lpItem->hdr.pszText); LISTVIEW_InvalidateRect(infoPtr, &rcBox);
/* free item */
COMCTL32_Free(lpItem);
bResult = DPA_Destroy(hdpaSubItems);
DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
DPA_DeletePtr(infoPtr->hdpaPosY, nItem);
} }
infoPtr->nItemCount--;
LISTVIEW_ShiftIndices(infoPtr, nItem, -1); LISTVIEW_ShiftIndices(infoPtr, nItem, -1);
/* align items (set position of each item) */ if (is_icon && (infoPtr->dwStyle & LVS_AUTOARRANGE))
if ((infoPtr->dwStyle & LVS_AUTOARRANGE) && (uView == LVS_SMALLICON || uView == LVS_ICON)) LISTVIEW_Arrange(infoPtr, LVA_DEFAULT);
LISTVIEW_Arrange(infoPtr, LVA_DEFAULT);
LISTVIEW_UpdateScroll(infoPtr); LISTVIEW_UpdateScroll(infoPtr);
LISTVIEW_InvalidateList(infoPtr); /* FIXME: optimize */ /* now is the invalidation fun */
}
/* there's nothing else to do in icon mode */
if (is_icon) return TRUE;
/* figure out the item's position */
if (uView == LVS_REPORT)
nPerCol = infoPtr->nItemCount + 1;
else /* LVS_LIST */
nPerCol = LISTVIEW_GetCountPerColumn(infoPtr);
nItemCol = nItem / nPerCol;
nItemRow = nItem % nPerCol;
LISTVIEW_GetOrigin(infoPtr, &Origin);
return bResult; /* move the items below up a slot */
rcScroll.left = nItemCol * infoPtr->nItemWidth;
rcScroll.top = nItemRow * infoPtr->nItemHeight;
rcScroll.right = rcScroll.left + infoPtr->nItemWidth;
rcScroll.bottom = nPerCol * infoPtr->nItemHeight;
OffsetRect(&rcScroll, Origin.x, Origin.y);
if (IntersectRect(&rcScroll, &rcScroll, &infoPtr->rcList))
ScrollWindowEx(infoPtr->hwndSelf, 0, -infoPtr->nItemHeight,
&rcScroll, &rcScroll, 0, 0, SW_ERASE | SW_INVALIDATE);
/* report has only that column, so we're done */
if (uView == LVS_REPORT) return TRUE;
/* now for LISTs, we have to deal with the columns to the right */
rcScroll.left = (nItemCol + 1) * infoPtr->nItemWidth;
rcScroll.top = 0;
rcScroll.right = (infoPtr->nItemCount / nPerCol + 1) * infoPtr->nItemWidth;
rcScroll.bottom = nPerCol * infoPtr->nItemHeight;
OffsetRect(&rcScroll, Origin.x, Origin.y);
if (IntersectRect(&rcScroll, &rcScroll, &infoPtr->rcList))
ScrollWindowEx(infoPtr->hwndSelf, 0, -infoPtr->nItemHeight,
&rcScroll, &rcScroll, 0, 0, SW_ERASE | SW_INVALIDATE);
return TRUE;
} }