From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/JabberG/jabber_treelist.cpp | 587 ++++++++++++++++++++++++++++++++++ 1 file changed, 587 insertions(+) create mode 100644 protocols/JabberG/jabber_treelist.cpp (limited to 'protocols/JabberG/jabber_treelist.cpp') diff --git a/protocols/JabberG/jabber_treelist.cpp b/protocols/JabberG/jabber_treelist.cpp new file mode 100644 index 0000000000..fb24e23c64 --- /dev/null +++ b/protocols/JabberG/jabber_treelist.cpp @@ -0,0 +1,587 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Copyright ( C ) 2002-04 Santithorn Bunchua +Copyright ( C ) 2005-11 George Hazan +Copyright ( C ) 2007 Victor Pavlychko + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or ( at your option ) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Revision : $Revision: 13452 $ +Last change on : $Date: 2011-03-17 21:12:56 +0200 (Чт, 17 мар 2011) $ +Last change by : $Author: george.hazan $ + +*/ + +#include "jabber.h" + +#define TLIF_VISIBLE 0x01 +#define TLIF_EXPANDED 0x02 +#define TLIF_MODIFIED 0x04 +#define TLIF_ROOT 0X08 +#define TLIF_HASITEM 0X10 +#define TLIF_REBUILD 0x20 +#define TLIF_FAKEPARENT 0x40 +#define TLIF_FILTERED 0x80 + +struct TTreeList_ItemInfo +{ + BYTE flags; + int indent, sortIndex; + + struct TTreeList_ItemInfo *parent; + int iIcon, iOverlay; + LIST text; + LPARAM data; + LIST subItems; + + TTreeList_ItemInfo(int columns = 3, int children = 5): + text(columns), subItems(children), parent(NULL), + flags(0), indent(0), sortIndex(0), iIcon(0), iOverlay(0), data(0) {} + ~TTreeList_ItemInfo() + { + int i; + for (i = text.getCount(); i--; ) + mir_free(text[i]); + text.destroy(); + for (i = subItems.getCount(); i--; ) + delete subItems[i]; + subItems.destroy(); + } +}; + +struct TTreeList_Data +{ + int mode, sortMode; + TCHAR *filter; + HTREELISTITEM hItemSelected; + TTreeList_ItemInfo *root; + + TTreeList_Data() + { + sortMode = 0; + filter = NULL; + mode = TLM_TREE; + root = NULL; + } + ~TTreeList_Data() + { + if (root) delete root; + if (filter) mir_free(filter); + } +}; + +// static utilities +static void sttTreeList_ResetIndex(HTREELISTITEM hItem, LPARAM data); +static void sttTreeList_SortItems(HTREELISTITEM hItem, LPARAM data); +static void sttTreeList_FilterItems(HTREELISTITEM hItem, LPARAM data); +static void sttTreeList_CreateItems(HTREELISTITEM hItem, LPARAM data); +static void sttTreeList_CreateItems_List(HTREELISTITEM hItem, LPARAM data); +static int CALLBACK sttTreeList_SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); + +static __forceinline void sttTreeList_SeWindowData(HWND hwnd, HANDLE data) +{ + SetPropA(hwnd, "Miranda.TreeList", (HANDLE)data); +} + +static __forceinline HANDLE sttTreeList_GeWindowData(HWND hwnd) +{ + return GetPropA(hwnd, "Miranda.TreeList"); +} + +// tree list implementation +LPARAM TreeList_GetData(HTREELISTITEM hItem) +{ + return hItem->data; +} + +HTREELISTITEM TreeList_GetRoot(HWND hwnd) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + return data->root; +} + +int TreeList_GetChildrenCount(HTREELISTITEM hItem) +{ + return hItem->subItems.getCount(); +} + +HTREELISTITEM TreeList_GetChild(HTREELISTITEM hItem, int i) +{ + return hItem->subItems[i]; +} + +void TreeList_Create(HWND hwnd) +{ + TTreeList_Data *data = new TTreeList_Data; + data->root = new TTreeList_ItemInfo; + data->root->flags = TLIF_EXPANDED|TLIF_VISIBLE|TLIF_ROOT; + data->root->indent = -1; + data->hItemSelected = data->root; + sttTreeList_SeWindowData(hwnd, data); + + ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_GRIDLINES | LVS_EX_INFOTIP ); + + HIMAGELIST hIml; + hIml = ImageList_Create(16, 16, ILC_MASK + ( IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16 ), 2, 1); + ListView_SetImageList (hwnd, hIml, LVSIL_SMALL); + + hIml = ImageList_Create(16, 16, ILC_MASK + ( IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16 ), 2, 1); + ImageList_AddIcon_Icolib(hIml, (HICON)JCallService( MS_SKIN_LOADICON, SKINICON_OTHER_GROUPOPEN, 0 )); + ImageList_AddIcon_Icolib(hIml, (HICON)JCallService( MS_SKIN_LOADICON, SKINICON_OTHER_GROUPSHUT, 0 )); + ImageList_AddIcon_Icolib(hIml, (HICON)JCallService( MS_SKIN_LOADICON, SKINICON_OTHER_DOWNARROW, 0 )); + ListView_SetImageList (hwnd, hIml, LVSIL_STATE); +} + +void TreeList_Destroy(HWND hwnd) +{ + ListView_DeleteAllItems(hwnd); + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + delete data; +} + +void TreeList_Reset(HWND hwnd) +{ + ListView_DeleteAllItems(hwnd); + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + delete data->root; + data->root = new TTreeList_ItemInfo; + data->root->flags = TLIF_EXPANDED|TLIF_VISIBLE|TLIF_ROOT; + data->root->indent = -1; + data->hItemSelected = data->root; +} + +void TreeList_SetMode(HWND hwnd, int mode) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + data->mode = mode; + ListView_DeleteAllItems(hwnd); + TreeList_Update(hwnd); +} + +void TreeList_SetSortMode(HWND hwnd, int col, BOOL descending) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + if ((col >= 0) && (col < 2)) + data->sortMode = 1 + col * 2 + (descending ? 1 : 0); + else + data->sortMode = 0; + TreeList_Update(hwnd); +} + +void TreeList_SetFilter(HWND hwnd, TCHAR *filter) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + if (data->filter) mir_free(data->filter); + data->filter = NULL; + if (filter) data->filter = mir_tstrdup(filter); + TreeList_Update(hwnd); +} + +HTREELISTITEM TreeList_GetActiveItem(HWND hwnd) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + lvi.iItem = ListView_GetNextItem(hwnd, -1, LVNI_SELECTED); + if (lvi.iItem < 0) + return (data->hItemSelected->flags & TLIF_ROOT) ? NULL : data->hItemSelected; + ListView_GetItem(hwnd, &lvi); + return (HTREELISTITEM)lvi.lParam; +} + +HTREELISTITEM TreeList_AddItem(HWND hwnd, HTREELISTITEM hParent, TCHAR *text, LPARAM nodeDdata) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + if (!hParent) hParent = data->root; + + TTreeList_ItemInfo *item = new TTreeList_ItemInfo; + item->data = nodeDdata; + item->parent = hParent; + item->text.insert(mir_tstrdup(text)); + item->flags |= TLIF_MODIFIED; + if (hParent->flags & TLIF_ROOT) + { + item->flags |= TLIF_EXPANDED; + data->hItemSelected = item; + } + item->indent = hParent->indent+1; + hParent->subItems.insert(item); + return item; +} + +void TreeList_ResetItem(HWND hwnd, HTREELISTITEM hParent) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + + for (int i = hParent->subItems.getCount(); i--; ) + delete hParent->subItems[i]; + hParent->subItems.destroy(); + + data->hItemSelected = hParent; + ListView_DeleteAllItems(hwnd); +} + +void TreeList_MakeFakeParent(HTREELISTITEM hItem, BOOL flag) +{ + if (flag) + hItem->flags |= TLIF_FAKEPARENT; + else + hItem->flags &= ~TLIF_FAKEPARENT; + hItem->flags |= TLIF_MODIFIED; +} + +void TreeList_AppendColumn(HTREELISTITEM hItem, TCHAR *text) +{ + hItem->text.insert(mir_tstrdup(text)); + hItem->flags |= TLIF_MODIFIED; +} + +int TreeList_AddIcon(HWND hwnd, HICON hIcon, int iOverlay) +{ + HIMAGELIST hIml = ListView_GetImageList(hwnd, LVSIL_SMALL); + int idx = ImageList_AddIcon(hIml, hIcon); + g_ReleaseIcon(hIcon); + if (iOverlay) ImageList_SetOverlayImage(hIml, idx, iOverlay); + return idx; +} + +void TreeList_SetIcon(HTREELISTITEM hItem, int iIcon, int iOverlay) +{ + if (iIcon >= 0) hItem->iIcon = iIcon; + if (iOverlay >= 0) hItem->iOverlay = iOverlay; + if ((iIcon >= 0) || (iOverlay >= 0)) hItem->flags |= TLIF_MODIFIED; +} + +void TreeList_RecursiveApply(HTREELISTITEM hItem, void (*func)(HTREELISTITEM, LPARAM), LPARAM data) +{ + for ( int i = 0; i < hItem->subItems.getCount(); i++ ) { + func( hItem->subItems[i], data ); + TreeList_RecursiveApply( hItem->subItems[i], func, data ); +} } + +void TreeList_Update(HWND hwnd) +{ + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(hwnd); + HTREELISTITEM hItem = data->root; + int sortIndex = 0; + + SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + if (data->sortMode) + TreeList_RecursiveApply(hItem, sttTreeList_SortItems, (LPARAM)data->sortMode); + TreeList_RecursiveApply(hItem, sttTreeList_ResetIndex, (LPARAM)&sortIndex); + if (data->filter) + TreeList_RecursiveApply(hItem, sttTreeList_FilterItems, (LPARAM)data->filter); + for ( int i = ListView_GetItemCount(hwnd); i--; ) { + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + lvi.iItem = i; + lvi.iSubItem = 0; + ListView_GetItem(hwnd, &lvi); + + HTREELISTITEM ptli = ( HTREELISTITEM )lvi.lParam; + if (( ptli->flags & TLIF_VISIBLE ) && (!data->filter || ( ptli->flags & TLIF_FILTERED ))) { + ptli->flags |= TLIF_HASITEM; + if ( ptli->flags & TLIF_MODIFIED ) { + lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE | LVIF_TEXT; + lvi.iItem = i; + lvi.iSubItem = 0; + lvi.pszText = ptli->text[0]; + lvi.stateMask = LVIS_OVERLAYMASK|LVIS_STATEIMAGEMASK; + lvi.iImage = ptli->iIcon; + if (data->mode == TLM_TREE) + { + lvi.state = + INDEXTOSTATEIMAGEMASK( + ((ptli->subItems.getCount() == 0) && !(ptli->flags & TLIF_FAKEPARENT)) ? 0 : + (ptli->flags & TLIF_EXPANDED) ? 1 : 2 ) | + INDEXTOOVERLAYMASK( ptli->iOverlay ); + } else + { + lvi.state = + INDEXTOSTATEIMAGEMASK( + ((ptli->subItems.getCount() == 0) && !(ptli->flags & TLIF_FAKEPARENT)) ? 0 : 3 ) | + INDEXTOOVERLAYMASK( ptli->iOverlay ); + } + ListView_SetItem(hwnd, &lvi); + for (int j = 1; j < ptli->text.getCount(); ++j) + ListView_SetItemText( hwnd, i, j, ptli->text[j]); + } + } + else ListView_DeleteItem(hwnd, i); + } + if (data->mode == TLM_TREE) + TreeList_RecursiveApply(hItem, sttTreeList_CreateItems, (LPARAM)hwnd); + else + { + for (int i = data->hItemSelected->subItems.getCount(); i--; ) + sttTreeList_CreateItems_List(data->hItemSelected->subItems[i], (LPARAM)hwnd); + for (HTREELISTITEM hItem = data->hItemSelected; !(hItem->flags & TLIF_ROOT); hItem = hItem->parent) + sttTreeList_CreateItems_List(hItem, (LPARAM)hwnd); + } + ListView_SortItems(hwnd, sttTreeList_SortFunc, 0); + SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); + UpdateWindow(hwnd); +} + +BOOL TreeList_ProcessMessage(HWND hwnd, UINT msg, WPARAM, LPARAM lparam, UINT idc, BOOL* ) +{ + LVITEM lvi = {0}; + + switch (msg) { + case WM_NOTIFY: + { + if (((LPNMHDR)lparam)->idFrom != idc) + break; + + TTreeList_Data *data = (TTreeList_Data *)sttTreeList_GeWindowData(GetDlgItem(hwnd, idc)); + switch (((LPNMHDR)lparam)->code) { + case LVN_COLUMNCLICK: + { + LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lparam; + TreeList_SetSortMode(lpnmlv->hdr.hwndFrom, lpnmlv->iSubItem, FALSE); + } + break; + + case LVN_ITEMACTIVATE: + if (data->mode == TLM_REPORT) { + LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lparam; + lvi.mask = LVIF_PARAM; + lvi.iItem = lpnmia->iItem; + ListView_GetItem(lpnmia->hdr.hwndFrom, &lvi); + + HTREELISTITEM hItem = (lvi.iItem < 0) ? data-> root : (HTREELISTITEM)lvi.lParam; + if (!hItem->subItems.getCount() && !(hItem->flags & TLIF_FAKEPARENT)) break; + data->hItemSelected = hItem; + + NMTREEVIEW nmtv; + nmtv.hdr.code = TVN_ITEMEXPANDED; + nmtv.hdr.hwndFrom = lpnmia->hdr.hwndFrom; + nmtv.hdr.idFrom = lpnmia->hdr.idFrom; + nmtv.itemNew.hItem = (HTREEITEM)lvi.lParam; + SendMessage(hwnd, WM_NOTIFY, lpnmia->hdr.idFrom, (LPARAM)&nmtv); + + if (data->mode == TLM_REPORT) + { + ListView_DeleteAllItems(lpnmia->hdr.hwndFrom); + TreeList_Update(lpnmia->hdr.hwndFrom); + } + } + break; + + case LVN_KEYDOWN: + if (data->mode == TLM_TREE) { + LPNMLVKEYDOWN lpnmlvk = (LPNMLVKEYDOWN)lparam; + + lvi.mask = LVIF_PARAM|LVIF_INDENT; + lvi.iItem = ListView_GetNextItem(lpnmlvk->hdr.hwndFrom, -1, LVNI_SELECTED); + if (lvi.iItem < 0) return FALSE; + lvi.iSubItem = 0; + ListView_GetItem(lpnmlvk->hdr.hwndFrom, &lvi); + HTREELISTITEM hItem = (HTREELISTITEM)lvi.lParam; + + switch (lpnmlvk->wVKey) { + case VK_SUBTRACT: + case VK_LEFT: + { + if ( hItem->subItems.getCount() && (hItem->flags & TLIF_EXPANDED )) { + hItem->flags &= ~TLIF_EXPANDED; + hItem->flags |= TLIF_MODIFIED; + TreeList_Update( lpnmlvk->hdr.hwndFrom ); + } + else if ( hItem->indent && (lpnmlvk->wVKey != VK_SUBTRACT )) { + for ( int i = lvi.iItem; i--; ) { + lvi.mask = LVIF_INDENT; + lvi.iItem = i; + lvi.iSubItem = 0; + ListView_GetItem(lpnmlvk->hdr.hwndFrom, &lvi); + if (lvi.iIndent < hItem->indent) { + lvi.mask = LVIF_STATE; + lvi.iItem = i; + lvi.iSubItem = 0; + lvi.state = lvi.stateMask = LVIS_FOCUSED|LVNI_SELECTED; + ListView_SetItem(lpnmlvk->hdr.hwndFrom, &lvi); + break; + } } } + break; + } + + case VK_ADD: + case VK_RIGHT: + if ( (hItem->subItems.getCount() || (hItem->flags & TLIF_FAKEPARENT)) && + !( hItem->flags & TLIF_EXPANDED )) + { + hItem->flags |= TLIF_EXPANDED; + hItem->flags |= TLIF_MODIFIED; + + NMTREEVIEW nmtv; + nmtv.hdr.code = TVN_ITEMEXPANDED; + nmtv.hdr.hwndFrom = lpnmlvk->hdr.hwndFrom; + nmtv.hdr.idFrom = lpnmlvk->hdr.idFrom; + nmtv.itemNew.hItem = (HTREEITEM)hItem; + SendMessage(hwnd, WM_NOTIFY, lpnmlvk->hdr.idFrom, (LPARAM)&nmtv); + TreeList_Update( lpnmlvk->hdr.hwndFrom ); + } + break; + } } + break; + + case NM_CLICK: + if (data->mode == TLM_TREE) { + LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lparam; + LVHITTESTINFO lvhti = {0}; + lvi.mask = LVIF_PARAM; + lvi.iItem = lpnmia->iItem; + ListView_GetItem(lpnmia->hdr.hwndFrom, &lvi); + lvhti.pt = lpnmia->ptAction; + ListView_HitTest(lpnmia->hdr.hwndFrom, &lvhti); + + HTREELISTITEM ptli = ( HTREELISTITEM )lvi.lParam; + if ((lvhti.iSubItem == 0) && ( (lvhti.flags&LVHT_ONITEM) == LVHT_ONITEMSTATEICON ) && + (ptli->subItems.getCount() || ptli->flags & TLIF_FAKEPARENT)) + { + if ( ptli->flags & TLIF_EXPANDED ) + ptli->flags &= ~TLIF_EXPANDED; + else { + ptli->flags |= TLIF_EXPANDED; + + NMTREEVIEW nmtv; + nmtv.hdr.code = TVN_ITEMEXPANDED; + nmtv.hdr.hwndFrom = lpnmia->hdr.hwndFrom; + nmtv.hdr.idFrom = lpnmia->hdr.idFrom; + nmtv.itemNew.hItem = (HTREEITEM)lvi.lParam; + SendMessage(hwnd, WM_NOTIFY, lpnmia->hdr.idFrom, (LPARAM)&nmtv); + } + ptli->flags |= TLIF_MODIFIED; + TreeList_Update( lpnmia->hdr.hwndFrom ); + } } + break; + } + break; + } } + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////// +static int sttTreeList_SortItems_Cmp0(const void *p1, const void *p2) { return lstrcmp((*(HTREELISTITEM *)p1)->text[0], (*(HTREELISTITEM *)p2)->text[0]); } +static int sttTreeList_SortItems_Cmp1(const void *p1, const void *p2) { return -lstrcmp((*(HTREELISTITEM *)p1)->text[0], (*(HTREELISTITEM *)p2)->text[0]); } +static int sttTreeList_SortItems_Cmp2(const void *p1, const void *p2) { return lstrcmp((*(HTREELISTITEM *)p1)->text[1], (*(HTREELISTITEM *)p2)->text[1]); } +static int sttTreeList_SortItems_Cmp3(const void *p1, const void *p2) { return -lstrcmp((*(HTREELISTITEM *)p1)->text[1], (*(HTREELISTITEM *)p2)->text[1]); } +static int sttTreeList_SortItems_Cmp4(const void *p1, const void *p2) { return lstrcmp((*(HTREELISTITEM *)p1)->text[2], (*(HTREELISTITEM *)p2)->text[2]); } +static int sttTreeList_SortItems_Cmp5(const void *p1, const void *p2) { return -lstrcmp((*(HTREELISTITEM *)p1)->text[2], (*(HTREELISTITEM *)p2)->text[2]); } + +static void sttTreeList_SortItems(HTREELISTITEM hItem, LPARAM data) +{ + if (!hItem->subItems.getCount()) return; + + typedef int (__cdecl *TQSortCmp)(const void *, const void *); + static TQSortCmp funcs[] = + { + sttTreeList_SortItems_Cmp0, + sttTreeList_SortItems_Cmp1, + sttTreeList_SortItems_Cmp2, + sttTreeList_SortItems_Cmp3, + sttTreeList_SortItems_Cmp4, + sttTreeList_SortItems_Cmp5, + }; + qsort(((SortedList *)&hItem->subItems)->items, hItem->subItems.getCount(), sizeof(void *), funcs[data-1]); +} + +static void sttTreeList_ResetIndex(HTREELISTITEM hItem, LPARAM data) +{ + hItem->flags &= ~TLIF_HASITEM; + + if ( !hItem->parent || (hItem->parent->flags & TLIF_VISIBLE) && (hItem->parent->flags & TLIF_EXPANDED )) + hItem->flags |= TLIF_VISIBLE; + else + hItem->flags &= ~TLIF_VISIBLE; + + hItem->sortIndex = (*(int *)data)++; +} + +static void sttTreeList_FilterItems(HTREELISTITEM hItem, LPARAM data) +{ + int i = 0; + for (i = 0; i < hItem->text.getCount(); ++i) + if (JabberStrIStr(hItem->text[i], (TCHAR *)data)) + break; + + if (i < hItem->text.getCount()) + { + while (!(hItem->flags & TLIF_ROOT)) + { + hItem->flags |= TLIF_FILTERED; + hItem = hItem->parent; + } + } else + { + hItem->flags &= ~TLIF_FILTERED; + } +} + +static void sttTreeList_CreateItems(HTREELISTITEM hItem, LPARAM data) +{ + TTreeList_Data *listData = (TTreeList_Data *)sttTreeList_GeWindowData((HWND)data); + if (( hItem->flags & TLIF_VISIBLE ) && (!listData->filter || ( hItem->flags & TLIF_FILTERED )) && !( hItem->flags & TLIF_HASITEM ) && !( hItem->flags & TLIF_ROOT )) { + LVITEM lvi = {0}; + lvi.mask = LVIF_INDENT | LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT | LVIF_STATE; + lvi.iIndent = hItem->indent; + lvi.lParam = (LPARAM)hItem; + lvi.pszText = hItem->text[0]; + lvi.stateMask = LVIS_OVERLAYMASK|LVIS_STATEIMAGEMASK; + lvi.iImage = hItem->iIcon; + lvi.state = + INDEXTOSTATEIMAGEMASK( + ((hItem->subItems.getCount() == 0) && !(hItem->flags & TLIF_FAKEPARENT)) ? 0 : + (hItem->flags & TLIF_EXPANDED) ? 1 : 2 ) | + INDEXTOOVERLAYMASK(hItem->iOverlay); + + int idx = ListView_InsertItem((HWND)data, &lvi); + for ( int i = 1; i < hItem->text.getCount(); i++ ) + ListView_SetItemText((HWND)data, idx, i, hItem->text[i]); +} } + +static void sttTreeList_CreateItems_List(HTREELISTITEM hItem, LPARAM data) +{ + TTreeList_Data *listData = (TTreeList_Data *)sttTreeList_GeWindowData((HWND)data); + if ((!listData->filter || ( hItem->flags & TLIF_FILTERED )) && !( hItem->flags & TLIF_HASITEM ) && !( hItem->flags & TLIF_ROOT )) { + LVITEM lvi = {0}; + lvi.mask = LVIF_INDENT | LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT | LVIF_STATE; + lvi.iIndent = hItem->indent; + lvi.lParam = (LPARAM)hItem; + lvi.pszText = hItem->text[0]; + lvi.stateMask = LVIS_OVERLAYMASK|LVIS_STATEIMAGEMASK; + lvi.iImage = hItem->iIcon; + lvi.state = + INDEXTOSTATEIMAGEMASK( + ((hItem->subItems.getCount() == 0) && !(hItem->flags & TLIF_FAKEPARENT)) ? 0 : 3 ) | + INDEXTOOVERLAYMASK( hItem->iOverlay ); + + int idx = ListView_InsertItem((HWND)data, &lvi); + for ( int i = 1; i < hItem->text.getCount(); i++ ) + ListView_SetItemText((HWND)data, idx, i, hItem->text[i]); +} } + +static int CALLBACK sttTreeList_SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM ) +{ + HTREELISTITEM p1 = ( HTREELISTITEM )lParam1, p2 = ( HTREELISTITEM )lParam2; + if ( p1->sortIndex < p2->sortIndex ) + return -1; + + if ( p1->sortIndex > p2->sortIndex ) + return +1; + + return 0; +} -- cgit v1.2.3