Commit 16dfb1a0 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

comctl32/treeview: Fix TVS_SINGLEEXPAND notifications order.

parent b3a61c13
...@@ -192,6 +192,15 @@ static const struct message parent_expand_seq[] = { ...@@ -192,6 +192,15 @@ static const struct message parent_expand_seq[] = {
{ 0 } { 0 }
}; };
static const struct message parent_singleexpand_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA },
{ WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA },
{ WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND },
{ WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA },
{ WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA },
{ 0 }
};
static const struct message empty_seq[] = { static const struct message empty_seq[] = {
{ 0 } { 0 }
}; };
...@@ -1231,6 +1240,25 @@ static void test_expandedimage(void) ...@@ -1231,6 +1240,25 @@ static void test_expandedimage(void)
DestroyWindow(hTree); DestroyWindow(hTree);
} }
static void test_TVS_SINGLEEXPAND(void)
{
HWND hTree;
BOOL ret;
hTree = create_treeview_control();
SetWindowLongA(hTree, GWL_STYLE, GetWindowLong(hTree, GWL_STYLE) | TVS_SINGLEEXPAND);
/* to avoid paiting related notifications */
ShowWindow(hTree, SW_HIDE);
fill_tree(hTree);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot);
ok(ret, "got %d\n", ret);
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_singleexpand_seq, "singleexpand notifications", FALSE);
DestroyWindow(hTree);
}
START_TEST(treeview) START_TEST(treeview)
{ {
HMODULE hComctl32; HMODULE hComctl32;
...@@ -1296,6 +1324,7 @@ START_TEST(treeview) ...@@ -1296,6 +1324,7 @@ START_TEST(treeview)
test_treeview_classinfo(); test_treeview_classinfo();
test_expandnotify(); test_expandnotify();
test_rect_retrieval_after_expand_with_select(); test_rect_retrieval_after_expand_with_select();
test_TVS_SINGLEEXPAND();
if (!load_v6_module(&ctx_cookie, &hCtx)) if (!load_v6_module(&ctx_cookie, &hCtx))
{ {
......
...@@ -3305,7 +3305,7 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, ...@@ -3305,7 +3305,7 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
static BOOL static BOOL
TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
BOOL bExpandPartial, BOOL bUser) BOOL partial, BOOL user)
{ {
LONG scrollDist; LONG scrollDist;
LONG orgNextTop = 0; LONG orgNextTop = 0;
...@@ -3313,7 +3313,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, ...@@ -3313,7 +3313,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
TREEVIEW_ITEM *nextItem, *tmpItem; TREEVIEW_ITEM *nextItem, *tmpItem;
BOOL sendsNotifications; BOOL sendsNotifications;
TRACE("(%p, %p, partial=%d, %d\n", infoPtr, wineItem, bExpandPartial, bUser); TRACE("(%p, %p, partial=%d, %d\n", infoPtr, wineItem, partial, user);
if (wineItem->state & TVIS_EXPANDED) if (wineItem->state & TVIS_EXPANDED)
return TRUE; return TRUE;
...@@ -3334,7 +3334,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, ...@@ -3334,7 +3334,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
TRACE("TVE_EXPAND %p %s\n", wineItem, TREEVIEW_ItemName(wineItem)); TRACE("TVE_EXPAND %p %s\n", wineItem, TREEVIEW_ItemName(wineItem));
sendsNotifications = bUser || ((wineItem->cChildren != 0) && sendsNotifications = user || ((wineItem->cChildren != 0) &&
!(wineItem->state & TVIS_EXPANDEDONCE)); !(wineItem->state & TVIS_EXPANDEDONCE));
if (sendsNotifications) if (sendsNotifications)
{ {
...@@ -3349,7 +3349,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, ...@@ -3349,7 +3349,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
wineItem->state |= TVIS_EXPANDED; wineItem->state |= TVIS_EXPANDED;
if (bExpandPartial) if (partial)
FIXME("TVE_EXPANDPARTIAL not implemented\n"); FIXME("TVE_EXPANDPARTIAL not implemented\n");
if (ISVISIBLE(wineItem)) if (ISVISIBLE(wineItem))
...@@ -3415,6 +3415,58 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, ...@@ -3415,6 +3415,58 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
return TRUE; return TRUE;
} }
/* Handler for TVS_SINGLEEXPAND behaviour. Used on response
to mouse messages and TVM_SELECTITEM.
selection - previously selected item, used to collapse a part of a tree
item - new selected item
*/
static void TREEVIEW_SingleExpand(TREEVIEW_INFO *infoPtr,
HTREEITEM selection, HTREEITEM item)
{
TREEVIEW_ITEM *SelItem;
if ((infoPtr->dwStyle & TVS_SINGLEEXPAND) == 0 || infoPtr->hwndEdit) return;
TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SINGLEEXPAND, TVC_UNKNOWN, TVIF_HANDLE | TVIF_PARAM, item, 0);
/*
* Close the previous selection all the way to the root
* as long as the new selection is not a child
*/
if(selection && (selection != item))
{
BOOL closeit = TRUE;
SelItem = item;
/* determine if the hitItem is a child of the currently selected item */
while(closeit && SelItem && TREEVIEW_ValidItem(infoPtr, SelItem) &&
(SelItem->parent != infoPtr->root))
{
closeit = (SelItem != selection);
SelItem = SelItem->parent;
}
if(closeit)
{
if(TREEVIEW_ValidItem(infoPtr, selection))
SelItem = selection;
while(SelItem && (SelItem != item) && TREEVIEW_ValidItem(infoPtr, SelItem) &&
SelItem->parent != infoPtr->root)
{
TREEVIEW_Collapse(infoPtr, SelItem, FALSE, FALSE);
SelItem = SelItem->parent;
}
}
}
/*
* Expand the current item
*/
TREEVIEW_Expand(infoPtr, item, FALSE, FALSE);
}
static BOOL static BOOL
TREEVIEW_Toggle(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, BOOL bUser) TREEVIEW_Toggle(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, BOOL bUser)
{ {
...@@ -4132,58 +4184,11 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) ...@@ -4132,58 +4184,11 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
} }
else if (ht.flags & (TVHT_ONITEMICON|TVHT_ONITEMLABEL)) /* select the item if the hit was inside of the icon or text */ else if (ht.flags & (TVHT_ONITEMICON|TVHT_ONITEMLABEL)) /* select the item if the hit was inside of the icon or text */
{ {
/* TREEVIEW_ITEM *selection = infoPtr->selectedItem;
* if we are TVS_SINGLEEXPAND then we want this single click to
* do a bunch of things.
*/
if((infoPtr->dwStyle & TVS_SINGLEEXPAND) &&
(infoPtr->hwndEdit == 0))
{
TREEVIEW_ITEM *SelItem;
/*
* Send the notification
*/
TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SINGLEEXPAND, TVC_UNKNOWN, TVIF_HANDLE | TVIF_PARAM, ht.hItem, 0);
/*
* Close the previous selection all the way to the root
* as long as the new selection is not a child
*/
if((infoPtr->selectedItem)
&& (infoPtr->selectedItem != ht.hItem))
{
BOOL closeit = TRUE;
SelItem = ht.hItem;
/* determine if the hitItem is a child of the currently selected item */
while(closeit && SelItem && TREEVIEW_ValidItem(infoPtr, SelItem) && (SelItem != infoPtr->root))
{
closeit = (SelItem != infoPtr->selectedItem);
SelItem = SelItem->parent;
}
if(closeit)
{
if(TREEVIEW_ValidItem(infoPtr, infoPtr->selectedItem))
SelItem = infoPtr->selectedItem;
while(SelItem && (SelItem != ht.hItem) && TREEVIEW_ValidItem(infoPtr, SelItem) && (SelItem != infoPtr->root))
{
TREEVIEW_Collapse(infoPtr, SelItem, FALSE, FALSE);
SelItem = SelItem->parent;
}
}
}
/*
* Expand the current item
*/
TREEVIEW_Expand(infoPtr, ht.hItem, TVE_TOGGLE, FALSE);
}
/* Select the current item */ /* Select the current item */
TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, ht.hItem, TVC_BYMOUSE); TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, ht.hItem, TVC_BYMOUSE);
TREEVIEW_SingleExpand(infoPtr, selection, ht.hItem);
} }
else if (ht.flags & TVHT_ONITEMSTATEICON) else if (ht.flags & TVHT_ONITEMSTATEICON)
{ {
...@@ -4415,7 +4420,9 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, ...@@ -4415,7 +4420,9 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect,
static LRESULT static LRESULT
TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item) TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
{ {
if (item != NULL && !TREEVIEW_ValidItem(infoPtr, item)) TREEVIEW_ITEM *selection = infoPtr->selectedItem;
if (item && !TREEVIEW_ValidItem(infoPtr, item))
return FALSE; return FALSE;
TRACE("%p (%s) %d\n", item, TREEVIEW_ItemName(item), wParam); TRACE("%p (%s) %d\n", item, TREEVIEW_ItemName(item), wParam);
...@@ -4423,6 +4430,8 @@ TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item) ...@@ -4423,6 +4430,8 @@ TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
if (!TREEVIEW_DoSelectItem(infoPtr, wParam, item, TVC_UNKNOWN)) if (!TREEVIEW_DoSelectItem(infoPtr, wParam, item, TVC_UNKNOWN))
return FALSE; return FALSE;
TREEVIEW_SingleExpand(infoPtr, selection, item);
return TRUE; return TRUE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment