From 4b0b7853103435d005c2013b925c6e3fc60402a6 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 26 May 2012 23:01:52 +0000 Subject: projects cleanup git-svn-id: http://svn.miranda-ng.org/main/trunk@191 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ExtraIcons/options.cpp | 866 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 866 insertions(+) create mode 100644 plugins/ExtraIcons/options.cpp (limited to 'plugins/ExtraIcons/options.cpp') diff --git a/plugins/ExtraIcons/options.cpp b/plugins/ExtraIcons/options.cpp new file mode 100644 index 0000000000..bbfc82629c --- /dev/null +++ b/plugins/ExtraIcons/options.cpp @@ -0,0 +1,866 @@ +/* + Copyright (C) 2009 Ricardo Pescuma Domenecci + + This is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this file; see the file license.txt. If + not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +#include "commons.h" + +#define ICON_SIZE 16 + +// Prototypes ///////////////////////////////////////////////////////////////////////////////////// + +HANDLE hOptHook = NULL; + +static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +// Functions ////////////////////////////////////////////////////////////////////////////////////// + + +int InitOptionsCallback(WPARAM wParam, LPARAM lParam) +{ + if (GetNumberOfSlots() < 1) + return 0; + + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszGroup = LPGENT("Contact List"); + odp.pszTitle = LPGENT("Extra icons"); + odp.pszTab = LPGENT("General"); + odp.pfnDlgProc = OptionsDlgProc; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.flags = ODPF_BOLDGROUPS | ODPF_EXPERTONLY; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + + return 0; +} + +void InitOptions() +{ + hOptHook = HookEvent(ME_OPT_INITIALISE, InitOptionsCallback); +} + +void DeInitOptions() +{ + UnhookEvent(hOptHook); +} + +BOOL ScreenToClient(HWND hWnd, LPRECT lpRect) +{ + BOOL ret; + POINT pt; + + pt.x = lpRect->left; + pt.y = lpRect->top; + + ret = ScreenToClient(hWnd, &pt); + + if (!ret) + return ret; + + lpRect->left = pt.x; + lpRect->top = pt.y; + + pt.x = lpRect->right; + pt.y = lpRect->bottom; + + ret = ScreenToClient(hWnd, &pt); + + lpRect->right = pt.x; + lpRect->bottom = pt.y; + + return ret; +} + +static void RemoveExtraIcons(int slot) +{ + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) + { + Clist_SetExtraIcon(hContact, slot, NULL); + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } +} + +#ifndef TVIS_FOCUSED +#define TVIS_FOCUSED 1 +#endif + +WNDPROC origTreeProc; + +static bool IsSelected(HWND tree, HTREEITEM hItem) +{ + return (TVIS_SELECTED & TreeView_GetItemState(tree, hItem, TVIS_SELECTED)) == TVIS_SELECTED; +} + +static void Tree_Select(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, TVIS_SELECTED, TVIS_SELECTED); +} + +static void Tree_Unselect(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, 0, TVIS_SELECTED); +} + +static void Tree_DropHilite(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, TVIS_DROPHILITED, TVIS_DROPHILITED); +} + +static void Tree_DropUnhilite(HWND tree, HTREEITEM hItem) +{ + TreeView_SetItemState(tree, hItem, 0, TVIS_DROPHILITED); +} + +static void UnselectAll(HWND tree) +{ + TreeView_SelectItem(tree, NULL); + + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + Tree_Unselect(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } +} + +static void Tree_SelectRange(HWND tree, HTREEITEM hStart, HTREEITEM hEnd) +{ + int start = 0; + int end = 0; + int i = 0; + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (hItem == hStart) + start = i; + if (hItem == hEnd) + end = i; + + i++; + hItem = TreeView_GetNextSibling(tree, hItem); + } + + if (end < start) + { + int tmp = start; + start = end; + end = tmp; + } + + i = 0; + hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (i >= start) + Tree_Select(tree, hItem); + if (i == end) + break; + + i++; + hItem = TreeView_GetNextSibling(tree, hItem); + } +} + +static int GetNumSelected(HWND tree) +{ + int ret = 0; + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (IsSelected(tree, hItem)) + ret++; + hItem = TreeView_GetNextSibling(tree, hItem); + } + return ret; +} + +static void Tree_GetSelected(HWND tree, vector &selected) +{ + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (IsSelected(tree, hItem)) + selected.push_back(hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } +} + +static void Tree_Select(HWND tree, vector &selected) +{ + for (unsigned int i = 0; i < selected.size(); i++) + if (selected[i] != NULL) + Tree_Select(tree, selected[i]); +} + +LRESULT CALLBACK TreeProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_LBUTTONDOWN: + { + DWORD pos = (DWORD) lParam; + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(pos); + hti.pt.y = (short) HIWORD(pos); + if (!TreeView_HitTest(hwndDlg, &hti)) + { + UnselectAll(hwndDlg); + break; + } + + if (!(wParam & (MK_CONTROL | MK_SHIFT)) || !(hti.flags & (TVHT_ONITEMICON | TVHT_ONITEMLABEL + | TVHT_ONITEMRIGHT))) + { + UnselectAll(hwndDlg); + TreeView_SelectItem(hwndDlg, hti.hItem); + break; + } + + if (wParam & MK_CONTROL) + { + vector selected; + Tree_GetSelected(hwndDlg, selected); + + + // Check if have to deselect it + for (unsigned int i = 0; i < selected.size(); i++) + { + if (selected[i] == hti.hItem) + { + // Deselect it + UnselectAll(hwndDlg); + selected[i] = NULL; + + if (i > 0) + hti.hItem = selected[0]; + + else if (i + 1 < selected.size()) + hti.hItem = selected[i + 1]; + + else + hti.hItem = NULL; + + break; + } + } + + TreeView_SelectItem(hwndDlg, hti.hItem); + Tree_Select(hwndDlg, selected); + } + else if (wParam & MK_SHIFT) + { + HTREEITEM hItem = TreeView_GetSelection(hwndDlg); + if (hItem == NULL) + break; + + vector selected; + Tree_GetSelected(hwndDlg, selected); + + TreeView_SelectItem(hwndDlg, hti.hItem); + Tree_Select(hwndDlg, selected); + Tree_SelectRange(hwndDlg, hItem, hti.hItem); + } + + return 0; + } + } + + return CallWindowProc(origTreeProc, hwndDlg, msg, wParam, lParam); +} + +static vector * Tree_GetIDs(HWND tree, HTREEITEM hItem) +{ + TVITEM tvi = { 0 }; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hItem; + TreeView_GetItem(tree, &tvi); + + return (vector *) tvi.lParam; +} + +static HTREEITEM Tree_AddExtraIcon(HWND tree, BaseExtraIcon *extra, bool selected, HTREEITEM hAfter = TVI_LAST) +{ + vector *ids = new vector ; + ids->push_back(extra->getID()); + + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = NULL; + tvis.hInsertAfter = hAfter; + tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; + tvis.item.stateMask = TVIS_STATEIMAGEMASK; + tvis.item.iSelectedImage = tvis.item.iImage = extra->getID(); + tvis.item.lParam = (LPARAM) ids; + tvis.item.pszText = (char *) extra->getDescription(); + tvis.item.state = INDEXTOSTATEIMAGEMASK(selected ? 2 : 1); + return TreeView_InsertItem(tree, &tvis); +} + +static HTREEITEM Tree_AddExtraIconGroup(HWND tree, vector &group, bool selected, HTREEITEM hAfter = TVI_LAST) +{ + vector *ids = new vector ; + string desc; + int img = 0; + for (unsigned int i = 0; i < group.size(); ++i) + { + BaseExtraIcon *extra = registeredExtraIcons[group[i] - 1]; + ids->push_back(extra->getID()); + + if (img == 0 && !IsEmpty(extra->getDescIcon())) + img = extra->getID(); + + if (i > 0) + desc += " / "; + desc += extra->getDescription(); + } + + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = NULL; + tvis.hInsertAfter = hAfter; + tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; + tvis.item.stateMask = TVIS_STATEIMAGEMASK; + tvis.item.iSelectedImage = tvis.item.iImage = img; + tvis.item.lParam = (LPARAM) ids; + tvis.item.pszText = (char *) desc.c_str(); + tvis.item.state = INDEXTOSTATEIMAGEMASK(selected ? 2 : 1); + return TreeView_InsertItem(tree, &tvis); +} + +static void GroupSelectedItems(HWND tree) +{ + vector toRemove; + vector ids; + bool selected = false; + HTREEITEM hPlace = NULL; + + + // Find items + + HTREEITEM hItem = TreeView_GetRoot(tree); + TVITEM tvi = { 0 }; + tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_STATE; + while (hItem) + { + if (IsSelected(tree, hItem)) + { + if (hPlace == NULL) + hPlace = hItem; + + tvi.hItem = hItem; + TreeView_GetItem(tree, &tvi); + + vector *iids = (vector *) tvi.lParam; + ids.insert(ids.end(), iids->begin(), iids->end()); + + if ((tvi.state & INDEXTOSTATEIMAGEMASK(3)) == INDEXTOSTATEIMAGEMASK(2)) + selected = true; + + toRemove.push_back(hItem); + } + + hItem = TreeView_GetNextSibling(tree, hItem); + } + + if (hPlace == NULL) + return; // None selected + + // Add new + int ii = ids.at(0); + ii = ids.at(1); + HTREEITEM hNew = Tree_AddExtraIconGroup(tree, ids, selected, hPlace); + + + // Remove old + for (unsigned int i = 0; i < toRemove.size(); ++i) + { + delete Tree_GetIDs(tree, toRemove[i]); + TreeView_DeleteItem(tree, toRemove[i]); + } + + // Select + UnselectAll(tree); + TreeView_SelectItem(tree, hNew); +} + +static void UngroupSelectedItems(HWND tree) +{ + HTREEITEM hItem = TreeView_GetSelection(tree); + if (hItem == NULL) + return; + vector *ids = Tree_GetIDs(tree, hItem); + if (ids->size() < 2) + return; + + bool selected = IsSelected(tree, hItem); + + for (size_t i = ids->size(); i > 0; --i) + { + BaseExtraIcon *extra = registeredExtraIcons[ids->at(i - 1) - 1]; + Tree_AddExtraIcon(tree, extra, selected, hItem); + } + + delete Tree_GetIDs(tree, hItem); + TreeView_DeleteItem(tree, hItem); + + UnselectAll(tree); +} + +static int ShowPopup(HWND hwndDlg, int popup) +{ + // Fix selection + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + HTREEITEM hSelected = (HTREEITEM) SendMessage(tree, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0); + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (hItem != hSelected && IsSelected(tree, hItem)) + Tree_DropHilite(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } + // InvalidateRect(tree, NULL, FALSE); + + HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_OPT_POPUP)); + HMENU submenu = GetSubMenu(menu, popup); + CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) submenu, 0); + + DWORD pos = GetMessagePos(); + int ret = TrackPopupMenu(submenu, TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_LEFTALIGN, LOWORD(pos), + HIWORD(pos), 0, hwndDlg, NULL); + + DestroyMenu(menu); + + + // Revert selection + hItem = TreeView_GetRoot(tree); + while (hItem) + { + if (hItem != hSelected && IsSelected(tree, hItem)) + Tree_DropUnhilite(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } + + return ret; +} + +static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + vector *a = (vector *) lParam1; + vector *b = (vector *) lParam2; + return registeredExtraIcons[a->at(0) - 1]->compare(registeredExtraIcons[b->at(0) - 1]); +} + +static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int dragging = 0; + static HANDLE hDragItem = NULL; + + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + int numSlots = GetNumberOfSlots(); + if (numSlots < (int) registeredExtraIcons.size()) + { + char txt[512]; + mir_snprintf(txt, MAX_REGS(txt), Translate("* only the first %d icons will be shown"), numSlots); + + HWND label = GetDlgItem(hwndDlg, IDC_MAX_ICONS_L); + SetWindowText(label, txt); + ShowWindow(label, SW_SHOW); + } + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + SetWindowLongPtr(tree, GWL_STYLE, GetWindowLong(tree, GWL_STYLE) | TVS_NOHSCROLL); + + int cx = GetSystemMetrics(SM_CXSMICON); + HIMAGELIST hImageList = ImageList_Create(cx, cx, ILC_COLOR32 | ILC_MASK, 2, 2); + + HICON hDefaultIcon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(IDI_EMPTY), IMAGE_ICON, cx, cx, + LR_DEFAULTCOLOR | LR_SHARED); + ImageList_AddIcon(hImageList, hDefaultIcon); + DestroyIcon(hDefaultIcon); + + unsigned int i; + for (i = 0; i < registeredExtraIcons.size(); ++i) + { + ExtraIcon *extra = registeredExtraIcons[i]; + + HICON hIcon = IcoLib_LoadIcon(extra->getDescIcon()); + + if (hIcon == NULL) + { + HICON hDefaultIcon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(IDI_EMPTY), IMAGE_ICON, cx, cx, + LR_DEFAULTCOLOR | LR_SHARED); + ImageList_AddIcon(hImageList, hDefaultIcon); + DestroyIcon(hDefaultIcon); + } + else + { + ImageList_AddIcon(hImageList, hIcon); + IcoLib_ReleaseIcon(hIcon); + } + } + TreeView_SetImageList(tree, hImageList, TVSIL_NORMAL); + + for (i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *extra = extraIconsBySlot[i]; + + if (extra->getType() == EXTRAICON_TYPE_GROUP) + { + ExtraIconGroup *group = (ExtraIconGroup *) extra; + vector ids; + for (unsigned int j = 0; j < group->items.size(); ++j) + ids.push_back(group->items[j]->getID()); + Tree_AddExtraIconGroup(tree, ids, extra->isEnabled()); + } + else + { + Tree_AddExtraIcon(tree, (BaseExtraIcon *) extra, extra->isEnabled()); + } + } + + TVSORTCB sort = { 0 }; + sort.hParent = NULL; + sort.lParam = 0; + sort.lpfnCompare = CompareFunc; + TreeView_SortChildrenCB(tree, &sort, 0); + + origTreeProc = (WNDPROC) SetWindowLongPtr(tree, -4, (INT_PTR)TreeProc); + + return TRUE; + } + case WM_NOTIFY: + { + LPNMHDR lpnmhdr = (LPNMHDR) lParam; + if (lpnmhdr->idFrom == 0) + { + if (lpnmhdr->code == (UINT) PSN_APPLY) + { + unsigned int i; + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + + // Store old slots + int *oldSlots = new int[registeredExtraIcons.size()]; + int lastUsedSlot = -1; + for (i = 0; i < registeredExtraIcons.size(); ++i) + { + if (extraIconsByHandle[i] == registeredExtraIcons[i]) + oldSlots[i] = registeredExtraIcons[i]->getSlot(); + else + // Remove old slot for groups to re-set images + oldSlots[i] = -1; + lastUsedSlot = MAX(lastUsedSlot, registeredExtraIcons[i]->getSlot()); + } + lastUsedSlot = MIN(lastUsedSlot, GetNumberOfSlots()); + + + // Get user data and create new groups + vector groups; + + BYTE pos = 0; + int firstEmptySlot = 0; + HTREEITEM ht = TreeView_GetRoot(tree); + TVITEM tvi = { 0 }; + tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + while (ht) + { + tvi.hItem = ht; + TreeView_GetItem(tree, &tvi); + + vector *ids = (vector *) tvi.lParam; + if (ids == NULL || ids->size() < 1) + continue; // ??? + + bool enabled = ((tvi.state & INDEXTOSTATEIMAGEMASK(3)) == INDEXTOSTATEIMAGEMASK(2)); + int slot = (enabled ? firstEmptySlot++ : -1); + if (slot >= GetNumberOfSlots()) + slot = -1; + + if (ids->size() == 1) + { + BaseExtraIcon *extra = registeredExtraIcons[ids->at(0) - 1]; + extra->setPosition(pos++); + extra->setSlot(slot); + } + else + { + char name[128]; + mir_snprintf(name, MAX_REGS(name), "__group_%d", groups.size()); + + ExtraIconGroup *group = new ExtraIconGroup(name); + + for (i = 0; i < ids->size(); ++i) + { + BaseExtraIcon *extra = registeredExtraIcons[ids->at(i) - 1]; + extra->setPosition(pos++); + + group->addExtraIcon(extra); + } + + group->setSlot(slot); + + groups.push_back(group); + } + + ht = TreeView_GetNextSibling(tree, ht); + } + + // Store data + for (i = 0; i < registeredExtraIcons.size(); ++i) + { + BaseExtraIcon *extra = registeredExtraIcons[i]; + + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "Position_%s", extra->getName()); + DBWriteContactSettingWord(NULL, MODULE_NAME, setting, extra->getPosition()); + + mir_snprintf(setting, MAX_REGS(setting), "Slot_%s", extra->getName()); + DBWriteContactSettingWord(NULL, MODULE_NAME, setting, extra->getSlot()); + } + + CallService(MS_DB_MODULE_DELETE, 0, (LPARAM) MODULE_NAME "Groups"); + DBWriteContactSettingWord(NULL, MODULE_NAME "Groups", "Count", groups.size()); + for (i = 0; i < groups.size(); ++i) + { + ExtraIconGroup *group = groups[i]; + + char setting[512]; + mir_snprintf(setting, MAX_REGS(setting), "%d_count", i); + DBWriteContactSettingWord(NULL, MODULE_NAME "Groups", setting, group->items.size()); + + for (unsigned int j = 0; j < group->items.size(); ++j) + { + BaseExtraIcon *extra = group->items[j]; + + mir_snprintf(setting, MAX_REGS(setting), "%d_%d", i, j); + DBWriteContactSettingString(NULL, MODULE_NAME "Groups", setting, extra->getName()); + } + } + + // Clean removed slots + for (int j = firstEmptySlot; j <= lastUsedSlot; ++j) + RemoveExtraIcons(j); + + + // Apply icons to new slots + RebuildListsBasedOnGroups(groups); + for (i = 0; i < extraIconsBySlot.size(); ++i) + { + ExtraIcon *extra = extraIconsBySlot[i]; + + if (extra->getType() != EXTRAICON_TYPE_GROUP) + { + if (oldSlots[((BaseExtraIcon *) extra)->getID() - 1] == extra->getSlot()) + continue; + } + + extra->applyIcons(); + } + + delete[] oldSlots; + + return TRUE; + } + } + else if (lpnmhdr->idFrom == IDC_EXTRAORDER) + { + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + switch (lpnmhdr->code) + { + case TVN_BEGINDRAG: + { + SetCapture(hwndDlg); + dragging = 1; + hDragItem = ((LPNMTREEVIEWA) lParam)->itemNew.hItem; + TreeView_SelectItem(tree, hDragItem); + break; + } + case NM_CLICK: + { + DWORD pos = GetMessagePos(); + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(pos); + hti.pt.y = (short) HIWORD(pos); + ScreenToClient(lpnmhdr->hwndFrom, &hti.pt); + if (TreeView_HitTest(lpnmhdr->hwndFrom, &hti)) + { + if (hti.flags & TVHT_ONITEMSTATEICON) + { + TreeView_SelectItem(tree, hti.hItem); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + } + break; + } + case TVN_KEYDOWN: + { + TV_KEYDOWN *nmkd = (TV_KEYDOWN *) lpnmhdr; + if (nmkd->wVKey == VK_SPACE) + { + // Determine the selected tree item. + HTREEITEM hItem = TreeView_GetSelection(tree); + if (hItem != NULL) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + break; + } + case NM_RCLICK: + { + HTREEITEM hSelected = (HTREEITEM) SendMessage(tree, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0); + if (hSelected != NULL && !IsSelected(tree, hSelected)) + { + UnselectAll(tree); + TreeView_SelectItem(tree, hSelected); + } + + int sels = GetNumSelected(tree); + if (sels > 1) + { + if (ShowPopup(hwndDlg, 0) == ID_GROUP) + { + GroupSelectedItems(tree); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + } + else if (sels == 1) + { + HTREEITEM hItem = TreeView_GetSelection(tree); + vector *ids = Tree_GetIDs(tree, hItem); + if (ids->size() > 1) + { + if (ShowPopup(hwndDlg, 1) == ID_UNGROUP) + { + UngroupSelectedItems(tree); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + } + } + } + break; + } + } + } + + break; + } + case WM_MOUSEMOVE: + { + if (!dragging) + break; + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(lParam); + hti.pt.y = (short) HIWORD(lParam); + ClientToScreen(hwndDlg, &hti.pt); + ScreenToClient(tree, &hti.pt); + TreeView_HitTest(tree, &hti); + if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) + { + HTREEITEM it = hti.hItem; + hti.pt.y -= TreeView_GetItemHeight(tree) / 2; + TreeView_HitTest(tree, &hti); + if (!(hti.flags & TVHT_ABOVE)) + TreeView_SetInsertMark(tree, hti.hItem, 1); + else + TreeView_SetInsertMark(tree, it, 0); + } + else + { + if (hti.flags & TVHT_ABOVE) + SendDlgItemMessage(hwndDlg, IDC_EXTRAORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEUP,0), 0); + if (hti.flags & TVHT_BELOW) + SendDlgItemMessage(hwndDlg, IDC_EXTRAORDER, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN,0), 0); + TreeView_SetInsertMark(tree, NULL, 0); + } + break; + } + case WM_LBUTTONUP: + { + if (!dragging) + break; + + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + + TreeView_SetInsertMark(tree, NULL, 0); + dragging = 0; + ReleaseCapture(); + + TVHITTESTINFO hti; + hti.pt.x = (short) LOWORD(lParam); + hti.pt.y = (short) HIWORD(lParam); + ClientToScreen(hwndDlg, &hti.pt); + ScreenToClient(tree, &hti.pt); + hti.pt.y -= TreeView_GetItemHeight(tree) / 2; + TreeView_HitTest(tree,&hti); + if (hDragItem == hti.hItem) + break; + + if (!(hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT | TVHT_ABOVE | TVHT_BELOW))) + break; + + if (hti.flags & TVHT_ABOVE) + hti.hItem = TVI_FIRST; + else if (hti.flags & TVHT_BELOW) + hti.hItem = TVI_LAST; + + TVINSERTSTRUCT tvis; + TCHAR name[512]; + tvis.item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; + tvis.item.stateMask = 0xFFFFFFFF; + tvis.item.pszText = name; + tvis.item.cchTextMax = MAX_REGS(name); + tvis.item.hItem = (HTREEITEM) hDragItem; + TreeView_GetItem(tree, &tvis.item); + + TreeView_DeleteItem(tree, hDragItem); + + tvis.hParent = NULL; + tvis.hInsertAfter = hti.hItem; + TreeView_SelectItem(tree, TreeView_InsertItem(tree, &tvis)); + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM) hwndDlg, 0); + + break; + } + case WM_DESTROY: + { + HWND tree = GetDlgItem(hwndDlg, IDC_EXTRAORDER); + HTREEITEM hItem = TreeView_GetRoot(tree); + while (hItem) + { + delete Tree_GetIDs(tree, hItem); + hItem = TreeView_GetNextSibling(tree, hItem); + } + + break; + } + } + + return 0; +} -- cgit v1.2.3