Module: wine Branch: master Commit: 16dfb1a03974c2627a3b24b51399ba27d3f981aa URL: http://source.winehq.org/git/wine.git/?a=commit;h=16dfb1a03974c2627a3b24b513...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Mon Jul 26 15:49:09 2010 +0400
comctl32/treeview: Fix TVS_SINGLEEXPAND notifications order.
---
dlls/comctl32/tests/treeview.c | 29 ++++++++++ dlls/comctl32/treeview.c | 117 +++++++++++++++++++++------------------ 2 files changed, 92 insertions(+), 54 deletions(-)
diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c index d3de85f..d1ca581 100644 --- a/dlls/comctl32/tests/treeview.c +++ b/dlls/comctl32/tests/treeview.c @@ -192,6 +192,15 @@ static const struct message parent_expand_seq[] = { { 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[] = { { 0 } }; @@ -1231,6 +1240,25 @@ static void test_expandedimage(void) 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) { HMODULE hComctl32; @@ -1296,6 +1324,7 @@ START_TEST(treeview) test_treeview_classinfo(); test_expandnotify(); test_rect_retrieval_after_expand_with_select(); + test_TVS_SINGLEEXPAND();
if (!load_v6_module(&ctx_cookie, &hCtx)) { diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index 8683b4a..3ee1639 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -3305,7 +3305,7 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
static BOOL TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, - BOOL bExpandPartial, BOOL bUser) + BOOL partial, BOOL user) { LONG scrollDist; LONG orgNextTop = 0; @@ -3313,7 +3313,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, TREEVIEW_ITEM *nextItem, *tmpItem; 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) return TRUE; @@ -3334,7 +3334,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *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)); if (sendsNotifications) { @@ -3349,7 +3349,7 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
wineItem->state |= TVIS_EXPANDED;
- if (bExpandPartial) + if (partial) FIXME("TVE_EXPANDPARTIAL not implemented\n");
if (ISVISIBLE(wineItem)) @@ -3415,6 +3415,58 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, 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 TREEVIEW_Toggle(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem, BOOL bUser) { @@ -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 */ { - /* - * 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); - } + TREEVIEW_ITEM *selection = infoPtr->selectedItem;
/* Select the current item */ TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, ht.hItem, TVC_BYMOUSE); + TREEVIEW_SingleExpand(infoPtr, selection, ht.hItem); } else if (ht.flags & TVHT_ONITEMSTATEICON) { @@ -4415,7 +4420,9 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, static LRESULT 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;
TRACE("%p (%s) %d\n", item, TREEVIEW_ItemName(item), wParam); @@ -4423,6 +4430,8 @@ TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item) if (!TREEVIEW_DoSelectItem(infoPtr, wParam, item, TVC_UNKNOWN)) return FALSE;
+ TREEVIEW_SingleExpand(infoPtr, selection, item); + return TRUE; }