From 57abc51aad272a656282a52a460a47abe24e07d6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 20 Jun 2012 23:51:53 +0000 Subject: - MS_SKIN2_ADDICON replaced with Skin_AddIcon; - SKINICONDESC_SIZE* constants removed and replaced with sizeof(sid); - added SIDF_PATH_UNICODE for all plugins; - dynamic translation fixed in the icolib options dialog git-svn-id: http://svn.miranda-ng.org/main/trunk@507 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/modules/clist/genmenu.cpp | 2 +- src/modules/icolib/IcoLib.h | 61 +- src/modules/icolib/skin2icons.cpp | 1136 ++----------------------------------- src/modules/icolib/skin2opts.cpp | 1051 ++++++++++++++++++++++++++++++++++ src/modules/skin/skinicons.cpp | 11 +- 5 files changed, 1139 insertions(+), 1122 deletions(-) create mode 100644 src/modules/icolib/skin2opts.cpp (limited to 'src/modules') diff --git a/src/modules/clist/genmenu.cpp b/src/modules/clist/genmenu.cpp index 7fcb9b32c7..f61921b4e1 100644 --- a/src/modules/clist/genmenu.cpp +++ b/src/modules/clist/genmenu.cpp @@ -1117,7 +1117,7 @@ static int MO_RegisterIcon(PMO_IntMenuItem pmi, void*) sid.pszDefaultFile = NULL; sid.pszDescription = buf; sid.hDefaultIcon = hIcon; - pmi->hIcolibItem = (HANDLE)CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + pmi->hIcolibItem = IcoLib_AddNewIcon(0, &sid); Safe_DestroyIcon(hIcon); if (hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)iconame)) { diff --git a/src/modules/icolib/IcoLib.h b/src/modules/icolib/IcoLib.h index 29bd85905b..30121729a8 100644 --- a/src/modules/icolib/IcoLib.h +++ b/src/modules/icolib/IcoLib.h @@ -20,23 +20,28 @@ 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. */ -typedef struct + +#define SECTIONPARAM_MAKE(index, level, flags) MAKELONG((index)&0xFFFF, MAKEWORD(level, flags)) +#define SECTIONPARAM_INDEX(lparam) LOWORD(lparam) +#define SECTIONPARAM_LEVEL(lparam) LOBYTE(HIWORD(lparam)) +#define SECTIONPARAM_FLAGS(lparam) HIBYTE(HIWORD(lparam)) +#define SECTIONPARAM_HAVEPAGE 0x0001 + +struct SectionItem { TCHAR* name; int flags; int maxOrder; int ref_count; -} - SectionItem; +}; -typedef struct +struct IconSourceFile { TCHAR* file; int ref_count; -} - IconSourceFile; +}; -typedef struct +struct IconSourceItem { IconSourceFile* file; int indx; @@ -49,10 +54,9 @@ typedef struct BYTE* icon_data; int icon_size; -} - IconSourceItem; +}; -typedef struct +struct IconItem { char* name; SectionItem* section; @@ -61,6 +65,7 @@ typedef struct TCHAR* default_file; int default_indx; int cx, cy; + int hLangpack; IconSourceItem* source_small; IconSourceItem* source_big; @@ -69,15 +74,35 @@ typedef struct TCHAR* temp_file; HICON temp_icon; BOOL temp_reset; -} - IconItem; -typedef struct -{ - char *paramName; - DWORD value; -} - TreeItem; + __inline TCHAR* getDescr() const { return LangPackTranslateStringT(hLangpack, description); } +}; // extracticon.c + UINT _ExtractIconEx(LPCTSTR lpszFile, int iconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT flags); + +void __fastcall SAFE_FREE(void** p); +void __fastcall SafeDestroyIcon(HICON* icon); + +int IconSourceItem_Release(IconSourceItem** pitem); +int IconSourceItem_ReleaseIcon(IconSourceItem* item); +HICON IconSourceItem_GetIcon(IconSourceItem* item); +IconSourceItem* GetIconSourceItem(const TCHAR* file, int indx, int cxIcon, int cyIcon); + +IconItem* IcoLib_FindHIcon(HICON hIcon, bool &big); +IconItem* IcoLib_FindIcon(const char* pszIconName); + +HICON IconItem_GetIcon(IconItem* item, bool big); + +int SkinOptionsInit(WPARAM, LPARAM); + +extern CRITICAL_SECTION csIconList; +extern LIST iconList; +extern LIST sectionList; + +extern BOOL bNeedRebuild; +extern int iconEventActive; +extern HICON hIconBlank; +extern HANDLE hIcons2ChangedEvent, hIconsChangedEvent; + diff --git a/src/modules/icolib/skin2icons.cpp b/src/modules/icolib/skin2icons.cpp index 810c15d741..2d6d9ab9cd 100644 --- a/src/modules/icolib/skin2icons.cpp +++ b/src/modules/icolib/skin2icons.cpp @@ -26,33 +26,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "IcoLib.h" static BOOL bModuleInitialized = FALSE; -static HANDLE hIcons2ChangedEvent, hIconsChangedEvent; -static HICON hIconBlank = NULL; +HANDLE hIcons2ChangedEvent, hIconsChangedEvent; -HANDLE hIcoLib_AddNewIcon, hIcoLib_RemoveIcon, hIcoLib_GetIcon, hIcoLib_GetIcon2, - hIcoLib_GetIconHandle, hIcoLib_IsManaged, hIcoLib_AddRef, hIcoLib_ReleaseIcon; +HICON hIconBlank = NULL; -static int iconEventActive = 0; +static HANDLE hIcoLib_AddNewIcon, hIcoLib_RemoveIcon, hIcoLib_GetIcon, hIcoLib_GetIcon2, + hIcoLib_GetIconHandle, hIcoLib_IsManaged, hIcoLib_AddRef, hIcoLib_ReleaseIcon; -static BOOL bNeedRebuild = FALSE; +int iconEventActive = 0; -struct IcoLibOptsData { - HWND hwndIndex; -}; +BOOL bNeedRebuild = FALSE; CRITICAL_SECTION csIconList; -#define SECTIONPARAM_MAKE(index, level, flags) MAKELONG((index)&0xFFFF, MAKEWORD(level, flags)) -#define SECTIONPARAM_INDEX(lparam) LOWORD(lparam) -#define SECTIONPARAM_LEVEL(lparam) LOBYTE(HIWORD(lparam)) -#define SECTIONPARAM_FLAGS(lparam) HIBYTE(HIWORD(lparam)) -#define SECTIONPARAM_HAVEPAGE 0x0001 - static int sttCompareSections(const SectionItem* p1, const SectionItem* p2) { return _tcscmp(p1->name, p2->name); } -static LIST sectionList(20, sttCompareSections); +LIST sectionList(20, sttCompareSections); static int sttCompareIconSourceFiles(const IconSourceFile* p1, const IconSourceFile* p2) { return _tcsicmp(p1->file, p2->file); @@ -91,23 +82,19 @@ static int sttCompareIcons(const IconItem* p1, const IconItem* p2) { return strcmp(p1->name, p2->name); } -static LIST iconList(20, sttCompareIcons); +LIST iconList(20, sttCompareIcons); ///////////////////////////////////////////////////////////////////////////////////////// // Utility functions -static void __fastcall MySetCursor(TCHAR* nCursor) -{ SetCursor(LoadCursor(NULL, nCursor)); -} - -static void __fastcall SAFE_FREE(void** p) +void __fastcall SAFE_FREE(void** p) { if (*p) { mir_free(*p); *p = NULL; } } -static void __fastcall SafeDestroyIcon(HICON* icon) +void __fastcall SafeDestroyIcon(HICON* icon) { if (*icon) { DestroyIcon(*icon); @@ -289,7 +276,7 @@ static int GetIconData(HICON icon, BYTE** data, int* size) #define VER30 0x00030000 -static HICON IconSourceItem_GetIcon(IconSourceItem* item) +HICON IconSourceItem_GetIcon(IconSourceItem* item) { if (item->icon) { item->icon_ref_count++; @@ -312,7 +299,7 @@ static HICON IconSourceItem_GetIcon(IconSourceItem* item) return item->icon; } -static int IconSourceItem_ReleaseIcon(IconSourceItem* item) +int IconSourceItem_ReleaseIcon(IconSourceItem* item) { if (item && item->icon_ref_count) { @@ -394,7 +381,7 @@ IconSourceItem* CreateStaticIconSourceItem(int cxIcon, int cyIcon) return newItem; } -static int IconSourceItem_Release(IconSourceItem** pitem) +int IconSourceItem_Release(IconSourceItem** pitem) { if (pitem && *pitem && (*pitem)->ref_count) { IconSourceItem* item = *pitem; @@ -418,32 +405,6 @@ static int IconSourceItem_Release(IconSourceItem** pitem) ///////////////////////////////////////////////////////////////////////////////////////// // Service functions -static HICON ExtractIconFromPath(const TCHAR *path, int cxIcon, int cyIcon) -{ - TCHAR *comma; - TCHAR file[ MAX_PATH ], fileFull[ MAX_PATH ]; - int n; - HICON hIcon; - - if ( !path) - return (HICON)NULL; - - lstrcpyn(file, path, SIZEOF(file)); - comma = _tcsrchr(file, ','); - if ( !comma) - n = 0; - else { - n = _ttoi(comma+1); - *comma = 0; - } - pathToAbsoluteT(file, fileFull, NULL); - hIcon = NULL; - - //SHOULD BE REPLACED WITH GOOD ENOUGH FUNCTION - _ExtractIconEx(fileFull, n, cxIcon, cyIcon, &hIcon, LR_COLOR); - return hIcon; -} - static SectionItem* IcoLib_AddSection(TCHAR *sectionName, BOOL create_new) { if ( !sectionName) @@ -481,7 +442,7 @@ static void IcoLib_RemoveSection(SectionItem* section) } } -static IconItem* IcoLib_FindIcon(const char* pszIconName) +IconItem* IcoLib_FindIcon(const char* pszIconName) { int indx; IconItem key = { (char*)pszIconName }; @@ -491,7 +452,7 @@ static IconItem* IcoLib_FindIcon(const char* pszIconName) return NULL; } -static IconItem* IcoLib_FindHIcon(HICON hIcon, bool &big) +IconItem* IcoLib_FindHIcon(HICON hIcon, bool &big) { IconItem* item = NULL; int indx; @@ -534,33 +495,24 @@ static void IcoLib_FreeIcon(IconItem* icon) ///////////////////////////////////////////////////////////////////////////////////////// // IcoLib_AddNewIcon -HANDLE IcoLib_AddNewIcon(SKINICONDESC* sid) +HANDLE IcoLib_AddNewIcon(int hLangpack, SKINICONDESC* sid) { - int utf = 0, utf_path = 0; - IconItem* item; - - if ( !sid->cbSize) + if (sid->cbSize != sizeof(SKINICONDESC)) return NULL; - if (sid->cbSize < SKINICONDESC_SIZE_V1) - return NULL; - - if (sid->cbSize >= SKINICONDESC_SIZE) { - utf = sid->flags & SIDF_UNICODE ? 1 : 0; - utf_path = sid->flags & SIDF_PATH_UNICODE ? 1 : 0; - } + bool utf = (sid->flags & SIDF_UNICODE) != 0; + bool utf_path = (sid->flags & SIDF_PATH_UNICODE) != 0; EnterCriticalSection(&csIconList); - item = IcoLib_FindIcon(sid->pszName); - if ( !item) { - item = (IconItem*)mir_alloc(sizeof(IconItem)); + IconItem* item = IcoLib_FindIcon(sid->pszName); + if (!item) { + item = (IconItem*)mir_calloc(sizeof(IconItem)); item->name = sid->pszName; iconList.insert(item); } else IcoLib_FreeIcon(item); - ZeroMemory(item, sizeof(*item)); item->name = mir_strdup(sid->pszName); if (utf) { item->description = mir_u2t(sid->pwszDescription); @@ -572,36 +524,28 @@ HANDLE IcoLib_AddNewIcon(SKINICONDESC* sid) item->section = IcoLib_AddSection(pwszSection, TRUE); SAFE_FREE((void**)&pwszSection); } + if (item->section) { item->section->ref_count++; item->orderID = ++item->section->maxOrder; } - else - item->orderID = 0; + else item->orderID = 0; if (sid->pszDefaultFile) { - if (utf_path) { - - WCHAR fileFull[ MAX_PATH ]; - - pathToAbsoluteW(sid->pwszDefaultFile, fileFull, NULL); - item->default_file = mir_wstrdup(fileFull); - } - else { - WCHAR *file = mir_a2u(sid->pszDefaultFile); - WCHAR fileFull[ MAX_PATH ]; - pathToAbsoluteW(file, fileFull, NULL); - SAFE_FREE((void**)&file); - item->default_file = mir_wstrdup(fileFull); - } } + WCHAR fileFull[ MAX_PATH ]; + if (utf_path) + pathToAbsoluteT(sid->pwszDefaultFile, fileFull, NULL); + else + pathToAbsoluteT( StrConvT(sid->pszDefaultFile), fileFull, NULL); + item->default_file = mir_wstrdup(fileFull); + } item->default_indx = sid->iDefaultIndex; - if (sid->cbSize >= SKINICONDESC_SIZE_V3) { - item->cx = sid->cx; - item->cy = sid->cy; - } + item->cx = sid->cx; + item->cy = sid->cy; + item->hLangpack = hLangpack; - if (sid->cbSize >= SKINICONDESC_SIZE_V2 && sid->hDefaultIcon) { + if (sid->hDefaultIcon) { bool big; IconItem* def_item = IcoLib_FindHIcon(sid->hDefaultIcon, big); if (def_item) { @@ -618,7 +562,7 @@ HANDLE IcoLib_AddNewIcon(SKINICONDESC* sid) } } - if (sid->cbSize >= SKINICONDESC_SIZE && item->section) + if (item->section) item->section->flags = sid->flags & SIDF_SORTED; LeaveCriticalSection(&csIconList); @@ -723,46 +667,6 @@ HICON IconItem_GetIcon(IconItem* item, bool big) return hIcon; } -///////////////////////////////////////////////////////////////////////////////////////// -// IconItem_GetIcon_Preview - -HICON IconItem_GetIcon_Preview(IconItem* item) -{ - HICON hIcon = NULL; - - if ( !item->temp_reset) { - HICON hRefIcon = IconItem_GetIcon(item, false); - hIcon = CopyIcon(hRefIcon); - if (item->source_small && item->source_small->icon == hRefIcon) - IconSourceItem_ReleaseIcon(item->source_small); - } - else { - if (item->default_icon) { - HICON hRefIcon = IconSourceItem_GetIcon(item->default_icon); - if (hRefIcon) { - hIcon = CopyIcon(hRefIcon); - if (item->default_icon->icon == hRefIcon) - IconSourceItem_ReleaseIcon(item->default_icon); - } } - - if ( !hIcon && item->default_file) { - IconSourceItem_Release(&item->default_icon); - item->default_icon = GetIconSourceItem(item->default_file, item->default_indx, item->cx, item->cy); - if (item->default_icon) { - HICON hRefIcon = IconSourceItem_GetIcon(item->default_icon); - if (hRefIcon) { - hIcon = CopyIcon(hRefIcon); - if (item->default_icon->icon == hRefIcon) - IconSourceItem_ReleaseIcon(item->default_icon); - } } } - - if ( !hIcon) - return CopyIcon(hIconBlank); - } - return hIcon; -} - - ///////////////////////////////////////////////////////////////////////////////////////// // IcoLib_GetIcon // lParam: pszIconName @@ -885,968 +789,6 @@ static INT_PTR IcoLib_AddRef(WPARAM wParam, LPARAM) return res; } -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib_ReleaseIcon -// lParam: pszIconName or NULL -// wParam: HICON or NULL - -int IcoLib_ReleaseIcon(HICON hIcon, char* szIconName, bool big) -{ - IconItem *item = NULL; - - EnterCriticalSection(&csIconList); - - if (szIconName) - item = IcoLib_FindIcon(szIconName); - - if ( !item && hIcon) // find by HICON - item = IcoLib_FindHIcon(hIcon, big); - - int res = 1; - if (item) { - IconSourceItem* source = big && !item->cx ? item->source_big : item->source_small; - if (source && source->icon_ref_count) { - if (iconEventActive) - source->icon_ref_count--; - else - IconSourceItem_ReleaseIcon(source); - res = 0; - } - } - - LeaveCriticalSection(&csIconList); - return res; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib GUI service routines - -static void LoadSectionIcons(TCHAR *filename, SectionItem* sectionActive) -{ - TCHAR path[ MAX_PATH ]; - int suffIndx; - HICON hIcon; - int indx; - - mir_sntprintf(path, SIZEOF(path), _T("%s,"), filename); - suffIndx = lstrlen(path); - - EnterCriticalSection(&csIconList); - - for (indx = 0; indx < iconList.getCount(); indx++) { - IconItem *item = iconList[ indx ]; - - if (item->default_file && item->section == sectionActive) { - _itot(item->default_indx, path + suffIndx, 10); - hIcon = ExtractIconFromPath(path, item->cx, item->cy); - if (hIcon) { - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - - item->temp_file = mir_tstrdup(path); - item->temp_icon = hIcon; - item->temp_reset = FALSE; - } } } - - LeaveCriticalSection(&csIconList); -} - -void LoadSubIcons(HWND htv, TCHAR *filename, HTREEITEM hItem) -{ - TVITEM tvi; - TreeItem *treeItem; - SectionItem* sectionActive; - - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - - TreeView_GetItem(htv, &tvi); - treeItem = (TreeItem *)tvi.lParam; - sectionActive = sectionList[ SECTIONPARAM_INDEX(treeItem->value) ]; - - tvi.hItem = TreeView_GetChild(htv, tvi.hItem); - while (tvi.hItem) { - LoadSubIcons(htv, filename, tvi.hItem); - tvi.hItem = TreeView_GetNextSibling(htv, tvi.hItem); - } - - if (SECTIONPARAM_FLAGS(treeItem->value) & SECTIONPARAM_HAVEPAGE) - LoadSectionIcons(filename, sectionActive); -} - -static void UndoChanges(int iconIndx, int cmd) -{ - IconItem *item = iconList[ iconIndx ]; - - if ( !item->temp_file && !item->temp_icon && item->temp_reset && cmd == ID_CANCELCHANGE) - item->temp_reset = FALSE; - else - { - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - } - - if (cmd == ID_RESET) - item->temp_reset = TRUE; -} - -void UndoSubItemChanges(HWND htv, HTREEITEM hItem, int cmd) -{ - TVITEM tvi = {0}; - TreeItem *treeItem; - int indx; - - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - TreeView_GetItem(htv, &tvi); - treeItem = (TreeItem *)tvi.lParam; - - if (SECTIONPARAM_FLAGS(treeItem->value) & SECTIONPARAM_HAVEPAGE) { - EnterCriticalSection(&csIconList); - - for (indx = 0; indx < iconList.getCount(); indx++) - if (iconList[ indx ]->section == sectionList[ SECTIONPARAM_INDEX(treeItem->value) ]) - UndoChanges(indx, cmd); - - LeaveCriticalSection(&csIconList); - } - - tvi.hItem = TreeView_GetChild(htv, tvi.hItem); - while (tvi.hItem) { - UndoSubItemChanges(htv, tvi.hItem, cmd); - tvi.hItem = TreeView_GetNextSibling(htv, tvi.hItem); -} } - -static void OpenIconsPage() -{ - CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://addons.miranda-im.org/index.php?action=display&id=35"); -} - -static int OpenPopupMenu(HWND hwndDlg) -{ - HMENU hMenu, hPopup; - POINT pt; - int cmd; - - GetCursorPos(&pt); - hMenu = LoadMenu(hMirandaInst, MAKEINTRESOURCE(IDR_ICOLIB_CONTEXT)); - hPopup = GetSubMenu(hMenu, 0); - TranslateMenu(hPopup); - cmd = TrackPopupMenu(hPopup, TPM_RIGHTBUTTON|TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); - DestroyMenu(hMenu); - return cmd; -} - -static TCHAR* OpenFileDlg(HWND hParent, const TCHAR* szFile, BOOL bAll) -{ - OPENFILENAME ofn = {0}; - TCHAR filter[512], *pfilter, file[MAX_PATH*2]; - - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = hParent; - - lstrcpy(filter, TranslateT("Icon Sets")); - if (bAll) - lstrcat(filter, _T(" (*.dll;*.icl;*.exe;*.ico)")); - else - lstrcat(filter, _T(" (*.dll)")); - - pfilter=filter+lstrlen(filter)+1; - if (bAll) - lstrcpy(pfilter, _T("*.DLL;*.ICL;*.EXE;*.ICO")); - else - lstrcpy(pfilter, _T("*.DLL")); - - pfilter += lstrlen(pfilter) + 1; - lstrcpy(pfilter, TranslateT("All Files")); - lstrcat(pfilter, _T(" (*)")); - pfilter += lstrlen(pfilter) + 1; - lstrcpy(pfilter, _T("*")); - pfilter += lstrlen(pfilter) + 1; - *pfilter='\0'; - - ofn.lpstrFilter = filter; - ofn.lpstrDefExt = _T("dll"); - lstrcpyn(file, szFile, SIZEOF(file)); - ofn.lpstrFile = file; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_DONTADDTORECENT; - ofn.nMaxFile = MAX_PATH*2; - - if ( !GetOpenFileName(&ofn)) - return NULL; - - return mir_tstrdup(file); -} - -// -// User interface -// - -#define DM_REBUILDICONSPREVIEW (WM_USER+10) -#define DM_CHANGEICON (WM_USER+11) -#define DM_CHANGESPECIFICICON (WM_USER+12) -#define DM_UPDATEICONSPREVIEW (WM_USER+13) -#define DM_REBUILD_CTREE (WM_USER+14) - -INT_PTR CALLBACK DlgProcIconImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -void DoOptionsChanged(HWND hwndDlg) -{ - SendMessage(hwndDlg, DM_UPDATEICONSPREVIEW, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); -} - -void DoIconsChanged(HWND hwndDlg) -{ - SendMessage(hwndDlg, DM_UPDATEICONSPREVIEW, 0, 0); - - iconEventActive = 1; // Disable icon destroying - performance boost - NotifyEventHooks(hIconsChangedEvent, 0, 0); - NotifyEventHooks(hIcons2ChangedEvent, 0, 0); - iconEventActive = 0; - - EnterCriticalSection(&csIconList); // Destroy unused icons - for (int indx = 0; indx < iconList.getCount(); indx++) { - IconItem *item = iconList[indx]; - if (item->source_small && !item->source_small->icon_ref_count) { - item->source_small->icon_ref_count++; - IconSourceItem_ReleaseIcon(item->source_small); - } - if (item->source_big && !item->source_big->icon_ref_count) { - item->source_big->icon_ref_count++; - IconSourceItem_ReleaseIcon(item->source_big); - } - } - LeaveCriticalSection(&csIconList); -} - -static HTREEITEM FindNamedTreeItemAt(HWND hwndTree, HTREEITEM hItem, const TCHAR *name) -{ - TVITEM tvi = {0}; - TCHAR str[MAX_PATH]; - - if (hItem) - tvi.hItem = TreeView_GetChild(hwndTree, hItem); - else - tvi.hItem = TreeView_GetRoot(hwndTree); - - if ( !name) - return tvi.hItem; - - tvi.mask = TVIF_TEXT; - tvi.pszText = str; - tvi.cchTextMax = MAX_PATH; - - while (tvi.hItem) - { - TreeView_GetItem(hwndTree, &tvi); - - if ( !lstrcmp(tvi.pszText, name)) - return tvi.hItem; - - tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); - } - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// icon import dialog's window procedure - -static int IconDlg_Resize(HWND, LPARAM, UTILRESIZECONTROL *urc) -{ - switch (urc->wId) { - case IDC_ICONSET: - return RD_ANCHORX_WIDTH | RD_ANCHORY_TOP; - - case IDC_BROWSE: - return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP; - - case IDC_PREVIEW: - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - - case IDC_GETMORE: - return RD_ANCHORX_CENTRE | RD_ANCHORY_BOTTOM; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default -} - -INT_PTR CALLBACK DlgProcIconImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static HWND hwndParent, hwndDragOver; - static int dragging; - static int dragItem, dropHiLite; - static HWND hPreview = NULL; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - hwndParent = (HWND)lParam; - hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW); - dragging = dragItem = 0; - ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32|ILC_MASK, 0, 100), LVSIL_NORMAL); - ListView_SetIconSpacing(hPreview, 56, 67); - { - RECT rcThis, rcParent; - int cxScreen = GetSystemMetrics(SM_CXSCREEN); - - GetWindowRect(hwndDlg, &rcThis); - GetWindowRect(hwndParent, &rcParent); - OffsetRect(&rcThis, rcParent.right-rcThis.left, 0); - OffsetRect(&rcThis, 0, rcParent.top-rcThis.top); - GetWindowRect(GetParent(hwndParent), &rcParent); - if (rcThis.right > cxScreen) { - OffsetRect(&rcParent, cxScreen-rcThis.right, 0); - OffsetRect(&rcThis, cxScreen-rcThis.right, 0); - MoveWindow(GetParent(hwndParent), rcParent.left, rcParent.top, rcParent.right-rcParent.left, rcParent.bottom-rcParent.top, TRUE); - } - MoveWindow(hwndDlg, rcThis.left, rcThis.top, rcThis.right-rcThis.left, rcThis.bottom-rcThis.top, FALSE); - GetClientRect(hwndDlg, &rcThis); - SendMessage(hwndDlg, WM_SIZE, 0, MAKELPARAM(rcThis.right-rcThis.left, rcThis.bottom-rcThis.top)); - } - - if (shAutoComplete) shAutoComplete(GetDlgItem(hwndDlg, IDC_ICONSET), 1); - SetDlgItemText(hwndDlg, IDC_ICONSET, _T("icons.dll")); - return TRUE; - - case DM_REBUILDICONSPREVIEW: - { - LVITEM lvi; - TCHAR filename[MAX_PATH], caption[64]; - HIMAGELIST hIml; - int count, i; - HICON hIcon; - - MySetCursor(IDC_WAIT); - ListView_DeleteAllItems(hPreview); - hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); - ImageList_RemoveAll(hIml); - GetDlgItemText(hwndDlg, IDC_ICONSET, filename, SIZEOF(filename)); - { - RECT rcPreview, rcGroup; - - GetWindowRect(hPreview, &rcPreview); - GetWindowRect(GetDlgItem(hwndDlg, IDC_IMPORTMULTI), &rcGroup); - //SetWindowPos(hPreview, 0, 0, 0, rcPreview.right-rcPreview.left, rcGroup.bottom-rcPreview.top, SWP_NOZORDER|SWP_NOMOVE); - } - - if (_taccess(filename, 0) != 0) { - MySetCursor(IDC_ARROW); - break; - } - - lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; - lvi.iSubItem = 0; - lvi.iItem = 0; - count = (int)_ExtractIconEx(filename, -1, 16, 16, NULL, LR_DEFAULTCOLOR); - for (i = 0; i < count; lvi.iItem++, i++) { - mir_sntprintf(caption, SIZEOF(caption), _T("%d"), i+1); - lvi.pszText = caption; - //hIcon = ExtractIcon(hMirandaInst, filename, i); - _ExtractIconEx(filename, i, 16, 16, &hIcon, LR_DEFAULTCOLOR); - lvi.iImage = ImageList_AddIcon(hIml, hIcon); - DestroyIcon(hIcon); - lvi.lParam = i; - ListView_InsertItem(hPreview, &lvi); - } - MySetCursor(IDC_ARROW); - } - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BROWSE: - { - TCHAR str[MAX_PATH]; - TCHAR *file; - - GetDlgItemText(hwndDlg, IDC_ICONSET, str, SIZEOF(str)); - if ( !(file = OpenFileDlg(GetParent(hwndDlg), str, TRUE))) break; - SetDlgItemText(hwndDlg, IDC_ICONSET, file); - SAFE_FREE((void**)&file); - } - break; - - case IDC_GETMORE: - OpenIconsPage(); - break; - - case IDC_ICONSET: - if (HIWORD(wParam) == EN_CHANGE) - SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, 0); - break; - } - break; - - case WM_MOUSEMOVE: - if (dragging) { - LVHITTESTINFO lvhti; - int onItem=0; - HWND hwndOver; - RECT rc; - POINT ptDrag; - HWND hPPreview = GetDlgItem(hwndParent, IDC_PREVIEW); - - lvhti.pt.x = (short)LOWORD(lParam); lvhti.pt.y = (short)HIWORD(lParam); - ClientToScreen(hwndDlg, &lvhti.pt); - hwndOver = WindowFromPoint(lvhti.pt); - GetWindowRect(hwndOver, &rc); - ptDrag.x = lvhti.pt.x - rc.left; ptDrag.y = lvhti.pt.y - rc.top; - if (hwndOver != hwndDragOver) { - ImageList_DragLeave(hwndDragOver); - hwndDragOver = hwndOver; - ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); - } - - ImageList_DragMove(ptDrag.x, ptDrag.y); - if (hwndOver == hPPreview) { - ScreenToClient(hPPreview, &lvhti.pt); - - if (ListView_HitTest(hPPreview, &lvhti) != -1) { - if (lvhti.iItem != dropHiLite) { - ImageList_DragLeave(hwndDragOver); - if (dropHiLite != -1) - ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED); - dropHiLite = lvhti.iItem; - ListView_SetItemState(hPPreview, dropHiLite, LVIS_DROPHILITED, LVIS_DROPHILITED); - UpdateWindow(hPPreview); - ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); - } - onItem = 1; - } } - - if ( !onItem && dropHiLite != -1) { - ImageList_DragLeave(hwndDragOver); - ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED); - UpdateWindow(hPPreview); - ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); - dropHiLite = -1; - } - MySetCursor(onItem ? IDC_ARROW : IDC_NO); - } - break; - - case WM_LBUTTONUP: - if (dragging) { - ReleaseCapture(); - ImageList_EndDrag(); - dragging = 0; - if (dropHiLite != -1) { - TCHAR path[MAX_PATH], fullPath[MAX_PATH], filename[MAX_PATH]; - LVITEM lvi; - - GetDlgItemText(hwndDlg, IDC_ICONSET, fullPath, SIZEOF(fullPath)); - CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)fullPath, (LPARAM)filename); - lvi.mask=LVIF_PARAM; - lvi.iItem = dragItem; lvi.iSubItem = 0; - ListView_GetItem(hPreview, &lvi); - mir_sntprintf(path, MAX_PATH, _T("%s,%d"), filename, (int)lvi.lParam); - SendMessage(hwndParent, DM_CHANGEICON, dropHiLite, (LPARAM)path); - ListView_SetItemState(GetDlgItem(hwndParent, IDC_PREVIEW), dropHiLite, 0, LVIS_DROPHILITED); - } } - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case IDC_PREVIEW: - switch (((LPNMHDR)lParam)->code) { - case LVN_BEGINDRAG: - SetCapture(hwndDlg); - dragging = 1; - dragItem = ((LPNMLISTVIEW)lParam)->iItem; - dropHiLite = -1; - ImageList_BeginDrag(ListView_GetImageList(hPreview, LVSIL_NORMAL), dragItem, GetSystemMetrics(SM_CXICON)/2, GetSystemMetrics(SM_CYICON)/2); - { - POINT pt; - RECT rc; - - GetCursorPos(&pt); - GetWindowRect(hwndDlg, &rc); - ImageList_DragEnter(hwndDlg, pt.x - rc.left, pt.y - rc.top); - hwndDragOver = hwndDlg; - } - break; - } - break; - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - EnableWindow(GetDlgItem(hwndParent, IDC_IMPORT), TRUE); - break; - - case WM_SIZE: - { // make the dlg resizeable - UTILRESIZEDIALOG urd = {0}; - - if (IsIconic(hwndDlg)) break; - urd.cbSize = sizeof(urd); - urd.hInstance = hMirandaInst; - urd.hwndDlg = hwndDlg; - urd.lParam = 0; // user-defined - urd.lpTemplate = MAKEINTRESOURCEA(IDD_ICOLIB_IMPORT); - urd.pfnResizer = IconDlg_Resize; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); - break; - } } - - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// IcoLib options window procedure - -static int CALLBACK DoSortIconsFunc(LPARAM lParam1, LPARAM lParam2, LPARAM) -{ return lstrcmpi(TranslateTS(iconList[lParam1]->description), TranslateTS(iconList[lParam2]->description)); -} - -static int CALLBACK DoSortIconsFuncByOrder(LPARAM lParam1, LPARAM lParam2, LPARAM) -{ return iconList[lParam1]->orderID - iconList[lParam2]->orderID; -} - -static void SaveCollapseState(HWND hwndTree) -{ - HTREEITEM hti; - TVITEM tvi; - - hti = TreeView_GetRoot(hwndTree); - while (hti != NULL) { - HTREEITEM ht; - TreeItem *treeItem; - - tvi.mask = TVIF_STATE | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM; - tvi.hItem = hti; - tvi.stateMask = (DWORD)-1; - TreeView_GetItem(hwndTree, &tvi); - - if (tvi.cChildren > 0) { - treeItem = (TreeItem *)tvi.lParam; - if (tvi.state & TVIS_EXPANDED) - DBWriteContactSettingByte(NULL, "SkinIconsUI", treeItem->paramName, TVIS_EXPANDED); - else - DBWriteContactSettingByte(NULL, "SkinIconsUI", treeItem->paramName, 0); - } - - ht = TreeView_GetChild(hwndTree, hti); - if (ht == NULL) { - ht = TreeView_GetNextSibling(hwndTree, hti); - while (ht == NULL) { - hti = TreeView_GetParent(hwndTree, hti); - if (hti == NULL) break; - ht = TreeView_GetNextSibling(hwndTree, hti); - } } - - hti = ht; -} } - -INT_PTR CALLBACK DlgProcIcoLibOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - struct IcoLibOptsData *dat; - static HTREEITEM prevItem = 0; - static HWND hPreview = NULL; - - dat = (struct IcoLibOptsData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW); - dat = (struct IcoLibOptsData*)mir_alloc(sizeof(struct IcoLibOptsData)); - dat->hwndIndex = NULL; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - // - // Reset temporary data & upload sections list - // - EnterCriticalSection(&csIconList); - { - int indx; - for (indx = 0; indx < iconList.getCount(); indx++) { - iconList[indx]->temp_file = NULL; - iconList[indx]->temp_icon = NULL; - iconList[indx]->temp_reset = FALSE; - } - bNeedRebuild = FALSE; - } - LeaveCriticalSection(&csIconList); - // - // Setup preview listview - // - ListView_SetUnicodeFormat(hPreview, TRUE); - ListView_SetExtendedListViewStyleEx(hPreview, LVS_EX_INFOTIP, LVS_EX_INFOTIP); - ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32|ILC_MASK, 0, 30), LVSIL_NORMAL); - ListView_SetIconSpacing(hPreview, 56, 67); - - SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); - return TRUE; - - case DM_REBUILD_CTREE: - { - HWND hwndTree = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); - int indx; - TCHAR itemName[1024]; - HTREEITEM hSection; - - if ( !hwndTree) break; - - TreeView_SelectItem(hwndTree, NULL); - TreeView_DeleteAllItems(hwndTree); - - for (indx = 0; indx < sectionList.getCount(); indx++) { - TCHAR* sectionName; - int sectionLevel = 0; - - hSection = NULL; - lstrcpy(itemName, sectionList[indx]->name); - sectionName = itemName; - - while (sectionName) { - // allow multi-level tree - TCHAR* pItemName = sectionName; - HTREEITEM hItem; - - if (sectionName = _tcschr(sectionName, '/')) { - // one level deeper - *sectionName = 0; - } - - pItemName = TranslateTS(pItemName); - - hItem = FindNamedTreeItemAt(hwndTree, hSection, pItemName); - if ( !sectionName || !hItem) { - if ( !hItem) { - TVINSERTSTRUCT tvis = {0}; - TreeItem *treeItem = (TreeItem *)mir_alloc(sizeof(TreeItem)); - treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, sectionName?0:SECTIONPARAM_HAVEPAGE); - treeItem->paramName = mir_t2a(itemName); - - tvis.hParent = hSection; - tvis.hInsertAfter = TVI_SORT; //TVI_LAST; - tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE; - tvis.item.pszText = pItemName; - tvis.item.lParam = (LPARAM) treeItem; - - tvis.item.state = tvis.item.stateMask = DBGetContactSettingByte(NULL, "SkinIconsUI", treeItem->paramName, TVIS_EXPANDED); - hItem = TreeView_InsertItem(hwndTree, &tvis); - } - else { - TVITEM tvi = {0}; - TreeItem *treeItem; - tvi.hItem = hItem; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - TreeView_GetItem(hwndTree, &tvi); - treeItem = (TreeItem *)tvi.lParam; - treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, SECTIONPARAM_HAVEPAGE); - } } - - if (sectionName) { - *sectionName = '/'; - sectionName++; - } - sectionLevel++; - - hSection = hItem; - } } - - ShowWindow(hwndTree, SW_SHOW); - - TreeView_SelectItem(hwndTree, FindNamedTreeItemAt(hwndTree, 0, NULL)); - } - break; - - // Rebuild preview to new section - case DM_REBUILDICONSPREVIEW: - { - LVITEM lvi = {0}; - HIMAGELIST hIml; - HICON hIcon; - SectionItem* sectionActive = (SectionItem*)lParam; - int indx; - - EnableWindow(hPreview, sectionActive != NULL); - - ListView_DeleteAllItems(hPreview); - hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); - ImageList_RemoveAll(hIml); - - if (sectionActive == NULL) - break; - - lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; - - EnterCriticalSection(&csIconList); - - for (indx = 0; indx < iconList.getCount(); indx++) { - IconItem *item = iconList[indx]; - - if (item->section == sectionActive) { - lvi.pszText = TranslateTS(item->description); - hIcon = item->temp_icon; - if ( !hIcon) - hIcon = IconItem_GetIcon_Preview(item); - lvi.iImage = ImageList_AddIcon(hIml, hIcon); - lvi.lParam = indx; - ListView_InsertItem(hPreview, &lvi); - if (hIcon != item->temp_icon) SafeDestroyIcon(&hIcon); - } } - - LeaveCriticalSection(&csIconList); - - if (sectionActive->flags & SIDF_SORTED) - ListView_SortItems(hPreview, DoSortIconsFunc, 0); - else - ListView_SortItems(hPreview, DoSortIconsFuncByOrder, 0); - } - break; - - // Refresh preview to new section - case DM_UPDATEICONSPREVIEW: - { - LVITEM lvi = {0}; - HICON hIcon; - int indx, count; - HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); - - lvi.mask = LVIF_IMAGE|LVIF_PARAM; - count = ListView_GetItemCount(hPreview); - - for (indx = 0; indx < count; indx++) { - lvi.iItem = indx; - ListView_GetItem(hPreview, &lvi); - EnterCriticalSection(&csIconList); - hIcon = iconList[lvi.lParam]->temp_icon; - if ( !hIcon) - hIcon = IconItem_GetIcon_Preview(iconList[lvi.lParam]); - LeaveCriticalSection(&csIconList); - - if (hIcon) - ImageList_ReplaceIcon(hIml, lvi.iImage, hIcon); - if (hIcon != iconList[lvi.lParam]->temp_icon) SafeDestroyIcon(&hIcon); - } - ListView_RedrawItems(hPreview, 0, count); - } - break; - - // Temporary change icon - only inside options dialog - case DM_CHANGEICON: - { - TCHAR *path=(TCHAR*)lParam; - LVITEM lvi = {0}; - IconItem *item; - - lvi.mask = LVIF_PARAM; - lvi.iItem = wParam; - ListView_GetItem(hPreview, &lvi); - - EnterCriticalSection(&csIconList); - item = iconList[ lvi.lParam ]; - - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - item->temp_file = mir_tstrdup(path); - item->temp_icon = (HICON)ExtractIconFromPath(path, item->cx, item->cy); - item->temp_reset = FALSE; - - LeaveCriticalSection(&csIconList); - DoOptionsChanged(hwndDlg); - } - break; - - case WM_COMMAND: - if (LOWORD(wParam) == IDC_IMPORT) { - dat->hwndIndex = CreateDialogParam(hMirandaInst, MAKEINTRESOURCE(IDD_ICOLIB_IMPORT), GetParent(hwndDlg), DlgProcIconImport, (LPARAM)hwndDlg); - EnableWindow((HWND)lParam, FALSE); - } - else if (LOWORD(wParam) == IDC_GETMORE) { - OpenIconsPage(); - break; - } - else if (LOWORD(wParam) == IDC_LOADICONS) { - TCHAR filetmp[1] = {0}; - TCHAR *file; - - if (file = OpenFileDlg(hwndDlg, filetmp, FALSE)) { - HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); - TCHAR filename[ MAX_PATH ]; - - CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)file, (LPARAM)filename); - SAFE_FREE((void**)&file); - - MySetCursor(IDC_WAIT); - LoadSubIcons(htv, filename, TreeView_GetSelection(htv)); - MySetCursor(IDC_ARROW); - - DoOptionsChanged(hwndDlg); - } } - break; - - case WM_CONTEXTMENU: - if ((HWND)wParam == hPreview) { - UINT count = ListView_GetSelectedCount(hPreview); - - if (count > 0) { - int cmd = OpenPopupMenu(hwndDlg); - switch(cmd) { - case ID_CANCELCHANGE: - case ID_RESET: - { - LVITEM lvi = {0}; - int itemIndx = -1; - - while ((itemIndx = ListView_GetNextItem(hPreview, itemIndx, LVNI_SELECTED)) != -1) { - lvi.mask = LVIF_PARAM; - lvi.iItem = itemIndx; //lvhti.iItem; - ListView_GetItem(hPreview, &lvi); - - UndoChanges(lvi.lParam, cmd); - } - - DoOptionsChanged(hwndDlg); - break; - } } } - } - else { - HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); - if ((HWND)wParam == htv) { - int cmd = OpenPopupMenu(hwndDlg); - - switch(cmd) { - case ID_CANCELCHANGE: - case ID_RESET: - UndoSubItemChanges(htv, TreeView_GetSelection(htv), cmd); - DoOptionsChanged(hwndDlg); - break; - } } } - break; - - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch(((LPNMHDR)lParam)->code) { - case PSN_APPLY: - { - int indx; - - EnterCriticalSection(&csIconList); - - for (indx = 0; indx < iconList.getCount(); indx++) { - IconItem *item = iconList[indx]; - if (item->temp_reset) { - DBDeleteContactSetting(NULL, "SkinIcons", item->name); - if (item->source_small != item->default_icon) { - IconSourceItem_Release(&item->source_small); - } - } - else if (item->temp_file) { - DBWriteContactSettingTString(NULL, "SkinIcons", item->name, item->temp_file); - IconSourceItem_Release(&item->source_small); - SafeDestroyIcon(&item->temp_icon); - } - } - LeaveCriticalSection(&csIconList); - - DoIconsChanged(hwndDlg); - return TRUE; - } } - break; - - case IDC_PREVIEW: - if (((LPNMHDR)lParam)->code == LVN_GETINFOTIP) - { - IconItem *item; - NMLVGETINFOTIP *pInfoTip = (NMLVGETINFOTIP *)lParam; - LVITEM lvi; - lvi.mask = LVIF_PARAM; - lvi.iItem = pInfoTip->iItem; - ListView_GetItem(pInfoTip->hdr.hwndFrom, &lvi); - - if (lvi.lParam < iconList.getCount()) { - item = iconList[lvi.lParam]; - if (item->temp_file) - _tcsncpy(pInfoTip->pszText, item->temp_file, pInfoTip->cchTextMax); - else if (item->default_file) - mir_sntprintf(pInfoTip->pszText, pInfoTip->cchTextMax, _T("%s, %d"), item->default_file, item->default_indx); - } - } - if (bNeedRebuild) { - EnterCriticalSection(&csIconList); - bNeedRebuild = FALSE; - LeaveCriticalSection(&csIconList); - SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); - } - break; - - case IDC_CATEGORYLIST: - switch(((NMHDR*)lParam)->code) { - case TVN_SELCHANGEDA: // !!!! This needs to be here - both !! - case TVN_SELCHANGEDW: - { - NMTREEVIEW *pnmtv = (NMTREEVIEW*)lParam; - TVITEM tvi = pnmtv->itemNew; - TreeItem *treeItem = (TreeItem *)tvi.lParam; - if (treeItem) - SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, (LPARAM)( - (SECTIONPARAM_FLAGS(treeItem->value)&SECTIONPARAM_HAVEPAGE)? - sectionList[ SECTIONPARAM_INDEX(treeItem->value) ] : NULL)); - break; - } - case TVN_DELETEITEMA: // no idea why both TVN_SELCHANGEDA/W should be there but let's keep this both too... - case TVN_DELETEITEMW: - { - TreeItem *treeItem = (TreeItem *)(((LPNMTREEVIEW)lParam)->itemOld.lParam); - if (treeItem) { - mir_free(treeItem->paramName); - mir_free(treeItem); - } - break; - } } - if (bNeedRebuild) { - EnterCriticalSection(&csIconList); - bNeedRebuild = FALSE; - LeaveCriticalSection(&csIconList); - SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); - } } - break; - case WM_DESTROY: - { - int indx; - - SaveCollapseState(GetDlgItem(hwndDlg, IDC_CATEGORYLIST)); - DestroyWindow(dat->hwndIndex); - - EnterCriticalSection(&csIconList); - for (indx = 0; indx < iconList.getCount(); indx++) { - IconItem *item = iconList[indx]; - - SAFE_FREE((void**)&item->temp_file); - SafeDestroyIcon(&item->temp_icon); - } - LeaveCriticalSection(&csIconList); - - SAFE_FREE((void**)&dat); - break; - } } - - return FALSE; -} - -static UINT iconsExpertOnlyControls[]={IDC_IMPORT}; - -static int SkinOptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = {0}; - odp.cbSize = sizeof(odp); - odp.hInstance = hMirandaInst; - odp.flags = ODPF_BOLDGROUPS; - odp.position = -180000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICOLIB); - odp.pszTitle = LPGEN("Icons"); - odp.pszGroup = LPGEN("Customize"); - odp.pfnDlgProc = DlgProcIcoLibOpts; - odp.expertOnlyControls = iconsExpertOnlyControls; - odp.nExpertOnlyControls = SIZEOF(iconsExpertOnlyControls); - Options_AddPage(wParam, &odp); - return 0; -} - static int SkinSystemModulesLoaded(WPARAM, LPARAM) { HookEvent(ME_OPT_INITIALISE, SkinOptionsInit); @@ -1856,8 +798,8 @@ static int SkinSystemModulesLoaded(WPARAM, LPARAM) ///////////////////////////////////////////////////////////////////////////////////////// // Module initialization and finalization procedure -static INT_PTR sttIcoLib_AddNewIcon(WPARAM, LPARAM lParam) -{ return (INT_PTR)IcoLib_AddNewIcon((SKINICONDESC*)lParam); +static INT_PTR sttIcoLib_AddNewIcon(WPARAM wParam, LPARAM lParam) +{ return (INT_PTR)IcoLib_AddNewIcon((int)wParam, (SKINICONDESC*)lParam); } static INT_PTR sttIcoLib_GetIcon(WPARAM wParam, LPARAM lParam) @@ -1891,7 +833,7 @@ int LoadIcoLibModule(void) hIconBlank = LoadIconEx(NULL, MAKEINTRESOURCE(IDI_BLANK), 0); InitializeCriticalSection(&csIconList); - hIcoLib_AddNewIcon = CreateServiceFunction(MS_SKIN2_ADDICON, sttIcoLib_AddNewIcon); + hIcoLib_AddNewIcon = CreateServiceFunction("Skin2/Icons/AddIcon", sttIcoLib_AddNewIcon); hIcoLib_RemoveIcon = CreateServiceFunction(MS_SKIN2_REMOVEICON, IcoLib_RemoveIcon); hIcoLib_GetIcon = CreateServiceFunction(MS_SKIN2_GETICON, sttIcoLib_GetIcon); hIcoLib_GetIconHandle = CreateServiceFunction(MS_SKIN2_GETICONHANDLE, sttIcoLib_GetIconHandle); diff --git a/src/modules/icolib/skin2opts.cpp b/src/modules/icolib/skin2opts.cpp new file mode 100644 index 0000000000..0d230d7930 --- /dev/null +++ b/src/modules/icolib/skin2opts.cpp @@ -0,0 +1,1051 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#include "..\..\core\commonheaders.h" + +#include "IcoLib.h" + +struct TreeItem +{ + char *paramName; + DWORD value; +}; + +struct IcoLibOptsData +{ + HWND hwndIndex; +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +static HICON ExtractIconFromPath(const TCHAR *path, int cxIcon, int cyIcon) +{ + TCHAR *comma; + TCHAR file[ MAX_PATH ], fileFull[ MAX_PATH ]; + int n; + HICON hIcon; + + if ( !path) + return (HICON)NULL; + + lstrcpyn(file, path, SIZEOF(file)); + comma = _tcsrchr(file, ','); + if ( !comma) + n = 0; + else { + n = _ttoi(comma+1); + *comma = 0; + } + pathToAbsoluteT(file, fileFull, NULL); + hIcon = NULL; + + //SHOULD BE REPLACED WITH GOOD ENOUGH FUNCTION + _ExtractIconEx(fileFull, n, cxIcon, cyIcon, &hIcon, LR_COLOR); + return hIcon; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// IcoLib_ReleaseIcon +// lParam: pszIconName or NULL +// wParam: HICON or NULL + +int IcoLib_ReleaseIcon(HICON hIcon, char* szIconName, bool big) +{ + IconItem *item = NULL; + + EnterCriticalSection(&csIconList); + + if (szIconName) + item = IcoLib_FindIcon(szIconName); + + if ( !item && hIcon) // find by HICON + item = IcoLib_FindHIcon(hIcon, big); + + int res = 1; + if (item) { + IconSourceItem* source = big && !item->cx ? item->source_big : item->source_small; + if (source && source->icon_ref_count) { + if (iconEventActive) + source->icon_ref_count--; + else + IconSourceItem_ReleaseIcon(source); + res = 0; + } + } + + LeaveCriticalSection(&csIconList); + return res; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// IconItem_GetIcon_Preview + +HICON IconItem_GetIcon_Preview(IconItem* item) +{ + HICON hIcon = NULL; + + if ( !item->temp_reset) { + HICON hRefIcon = IconItem_GetIcon(item, false); + hIcon = CopyIcon(hRefIcon); + if (item->source_small && item->source_small->icon == hRefIcon) + IconSourceItem_ReleaseIcon(item->source_small); + } + else { + if (item->default_icon) { + HICON hRefIcon = IconSourceItem_GetIcon(item->default_icon); + if (hRefIcon) { + hIcon = CopyIcon(hRefIcon); + if (item->default_icon->icon == hRefIcon) + IconSourceItem_ReleaseIcon(item->default_icon); + } } + + if ( !hIcon && item->default_file) { + IconSourceItem_Release(&item->default_icon); + item->default_icon = GetIconSourceItem(item->default_file, item->default_indx, item->cx, item->cy); + if (item->default_icon) { + HICON hRefIcon = IconSourceItem_GetIcon(item->default_icon); + if (hRefIcon) { + hIcon = CopyIcon(hRefIcon); + if (item->default_icon->icon == hRefIcon) + IconSourceItem_ReleaseIcon(item->default_icon); + } } } + + if ( !hIcon) + return CopyIcon(hIconBlank); + } + return hIcon; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// IcoLib GUI service routines + +static void __fastcall MySetCursor(TCHAR* nCursor) +{ SetCursor(LoadCursor(NULL, nCursor)); +} + +static void LoadSectionIcons(TCHAR *filename, SectionItem* sectionActive) +{ + TCHAR path[ MAX_PATH ]; + mir_sntprintf(path, SIZEOF(path), _T("%s,"), filename); + int suffIndx = lstrlen(path); + + EnterCriticalSection(&csIconList); + + for (int indx = 0; indx < iconList.getCount(); indx++) { + IconItem *item = iconList[ indx ]; + + if (item->default_file && item->section == sectionActive) { + _itot(item->default_indx, path + suffIndx, 10); + HICON hIcon = ExtractIconFromPath(path, item->cx, item->cy); + if (!hIcon) + continue; + + SAFE_FREE((void**)&item->temp_file); + SafeDestroyIcon(&item->temp_icon); + + item->temp_file = mir_tstrdup(path); + item->temp_icon = hIcon; + item->temp_reset = FALSE; + } } + + LeaveCriticalSection(&csIconList); +} + +void LoadSubIcons(HWND htv, TCHAR *filename, HTREEITEM hItem) +{ + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hItem; + TreeView_GetItem(htv, &tvi); + + TreeItem *treeItem = (TreeItem *)tvi.lParam; + SectionItem* sectionActive = sectionList[ SECTIONPARAM_INDEX(treeItem->value) ]; + + tvi.hItem = TreeView_GetChild(htv, tvi.hItem); + while (tvi.hItem) { + LoadSubIcons(htv, filename, tvi.hItem); + tvi.hItem = TreeView_GetNextSibling(htv, tvi.hItem); + } + + if (SECTIONPARAM_FLAGS(treeItem->value) & SECTIONPARAM_HAVEPAGE) + LoadSectionIcons(filename, sectionActive); +} + +static void UndoChanges(int iconIndx, int cmd) +{ + IconItem *item = iconList[ iconIndx ]; + + if ( !item->temp_file && !item->temp_icon && item->temp_reset && cmd == ID_CANCELCHANGE) + item->temp_reset = FALSE; + else { + SAFE_FREE((void**)&item->temp_file); + SafeDestroyIcon(&item->temp_icon); + } + + if (cmd == ID_RESET) + item->temp_reset = TRUE; +} + +void UndoSubItemChanges(HWND htv, HTREEITEM hItem, int cmd) +{ + TVITEM tvi = {0}; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hItem; + TreeView_GetItem(htv, &tvi); + + TreeItem *treeItem = (TreeItem *)tvi.lParam; + if (SECTIONPARAM_FLAGS(treeItem->value) & SECTIONPARAM_HAVEPAGE) { + EnterCriticalSection(&csIconList); + + for (int indx = 0; indx < iconList.getCount(); indx++) + if (iconList[ indx ]->section == sectionList[ SECTIONPARAM_INDEX(treeItem->value) ]) + UndoChanges(indx, cmd); + + LeaveCriticalSection(&csIconList); + } + + tvi.hItem = TreeView_GetChild(htv, tvi.hItem); + while (tvi.hItem) { + UndoSubItemChanges(htv, tvi.hItem, cmd); + tvi.hItem = TreeView_GetNextSibling(htv, tvi.hItem); +} } + +static void OpenIconsPage() +{ + CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://addons.miranda-im.org/index.php?action=display&id=35"); +} + +static int OpenPopupMenu(HWND hwndDlg) +{ + HMENU hMenu, hPopup; + POINT pt; + int cmd; + + GetCursorPos(&pt); + hMenu = LoadMenu(hMirandaInst, MAKEINTRESOURCE(IDR_ICOLIB_CONTEXT)); + hPopup = GetSubMenu(hMenu, 0); + TranslateMenu(hPopup); + cmd = TrackPopupMenu(hPopup, TPM_RIGHTBUTTON|TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); + DestroyMenu(hMenu); + return cmd; +} + +static TCHAR* OpenFileDlg(HWND hParent, const TCHAR* szFile, BOOL bAll) +{ + OPENFILENAME ofn = {0}; + TCHAR filter[512], *pfilter, file[MAX_PATH*2]; + + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + ofn.hwndOwner = hParent; + + lstrcpy(filter, TranslateT("Icon Sets")); + if (bAll) + lstrcat(filter, _T(" (*.dll;*.icl;*.exe;*.ico)")); + else + lstrcat(filter, _T(" (*.dll)")); + + pfilter=filter+lstrlen(filter)+1; + if (bAll) + lstrcpy(pfilter, _T("*.DLL;*.ICL;*.EXE;*.ICO")); + else + lstrcpy(pfilter, _T("*.DLL")); + + pfilter += lstrlen(pfilter) + 1; + lstrcpy(pfilter, TranslateT("All Files")); + lstrcat(pfilter, _T(" (*)")); + pfilter += lstrlen(pfilter) + 1; + lstrcpy(pfilter, _T("*")); + pfilter += lstrlen(pfilter) + 1; + *pfilter='\0'; + + ofn.lpstrFilter = filter; + ofn.lpstrDefExt = _T("dll"); + lstrcpyn(file, szFile, SIZEOF(file)); + ofn.lpstrFile = file; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_DONTADDTORECENT; + ofn.nMaxFile = MAX_PATH*2; + + if ( !GetOpenFileName(&ofn)) + return NULL; + + return mir_tstrdup(file); +} + +// +// User interface +// + +#define DM_REBUILDICONSPREVIEW (WM_USER+10) +#define DM_CHANGEICON (WM_USER+11) +#define DM_CHANGESPECIFICICON (WM_USER+12) +#define DM_UPDATEICONSPREVIEW (WM_USER+13) +#define DM_REBUILD_CTREE (WM_USER+14) + +INT_PTR CALLBACK DlgProcIconImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +void DoOptionsChanged(HWND hwndDlg) +{ + SendMessage(hwndDlg, DM_UPDATEICONSPREVIEW, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); +} + +void DoIconsChanged(HWND hwndDlg) +{ + SendMessage(hwndDlg, DM_UPDATEICONSPREVIEW, 0, 0); + + iconEventActive = 1; // Disable icon destroying - performance boost + NotifyEventHooks(hIconsChangedEvent, 0, 0); + NotifyEventHooks(hIcons2ChangedEvent, 0, 0); + iconEventActive = 0; + + EnterCriticalSection(&csIconList); // Destroy unused icons + for (int indx = 0; indx < iconList.getCount(); indx++) { + IconItem *item = iconList[indx]; + if (item->source_small && !item->source_small->icon_ref_count) { + item->source_small->icon_ref_count++; + IconSourceItem_ReleaseIcon(item->source_small); + } + if (item->source_big && !item->source_big->icon_ref_count) { + item->source_big->icon_ref_count++; + IconSourceItem_ReleaseIcon(item->source_big); + } + } + LeaveCriticalSection(&csIconList); +} + +static HTREEITEM FindNamedTreeItemAt(HWND hwndTree, HTREEITEM hItem, const TCHAR *name) +{ + TVITEM tvi = {0}; + TCHAR str[MAX_PATH]; + + if (hItem) + tvi.hItem = TreeView_GetChild(hwndTree, hItem); + else + tvi.hItem = TreeView_GetRoot(hwndTree); + + if ( !name) + return tvi.hItem; + + tvi.mask = TVIF_TEXT; + tvi.pszText = str; + tvi.cchTextMax = MAX_PATH; + + while (tvi.hItem) + { + TreeView_GetItem(hwndTree, &tvi); + + if ( !lstrcmp(tvi.pszText, name)) + return tvi.hItem; + + tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem); + } + return NULL; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// icon import dialog's window procedure + +static int IconDlg_Resize(HWND, LPARAM, UTILRESIZECONTROL *urc) +{ + switch (urc->wId) { + case IDC_ICONSET: + return RD_ANCHORX_WIDTH | RD_ANCHORY_TOP; + + case IDC_BROWSE: + return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP; + + case IDC_PREVIEW: + return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + + case IDC_GETMORE: + return RD_ANCHORX_CENTRE | RD_ANCHORY_BOTTOM; + } + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default +} + +INT_PTR CALLBACK DlgProcIconImport(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static HWND hwndParent, hwndDragOver; + static int dragging; + static int dragItem, dropHiLite; + static HWND hPreview = NULL; + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + hwndParent = (HWND)lParam; + hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW); + dragging = dragItem = 0; + ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32|ILC_MASK, 0, 100), LVSIL_NORMAL); + ListView_SetIconSpacing(hPreview, 56, 67); + { + RECT rcThis, rcParent; + int cxScreen = GetSystemMetrics(SM_CXSCREEN); + + GetWindowRect(hwndDlg, &rcThis); + GetWindowRect(hwndParent, &rcParent); + OffsetRect(&rcThis, rcParent.right-rcThis.left, 0); + OffsetRect(&rcThis, 0, rcParent.top-rcThis.top); + GetWindowRect(GetParent(hwndParent), &rcParent); + if (rcThis.right > cxScreen) { + OffsetRect(&rcParent, cxScreen-rcThis.right, 0); + OffsetRect(&rcThis, cxScreen-rcThis.right, 0); + MoveWindow(GetParent(hwndParent), rcParent.left, rcParent.top, rcParent.right-rcParent.left, rcParent.bottom-rcParent.top, TRUE); + } + MoveWindow(hwndDlg, rcThis.left, rcThis.top, rcThis.right-rcThis.left, rcThis.bottom-rcThis.top, FALSE); + GetClientRect(hwndDlg, &rcThis); + SendMessage(hwndDlg, WM_SIZE, 0, MAKELPARAM(rcThis.right-rcThis.left, rcThis.bottom-rcThis.top)); + } + + if (shAutoComplete) + shAutoComplete(GetDlgItem(hwndDlg, IDC_ICONSET), 1); + + SetDlgItemText(hwndDlg, IDC_ICONSET, _T("icons.dll")); + return TRUE; + + case DM_REBUILDICONSPREVIEW: + { + MySetCursor(IDC_WAIT); + ListView_DeleteAllItems(hPreview); + HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); + ImageList_RemoveAll(hIml); + + TCHAR filename[MAX_PATH], caption[64]; + GetDlgItemText(hwndDlg, IDC_ICONSET, filename, SIZEOF(filename)); + { + RECT rcPreview, rcGroup; + + GetWindowRect(hPreview, &rcPreview); + GetWindowRect(GetDlgItem(hwndDlg, IDC_IMPORTMULTI), &rcGroup); + //SetWindowPos(hPreview, 0, 0, 0, rcPreview.right-rcPreview.left, rcGroup.bottom-rcPreview.top, SWP_NOZORDER|SWP_NOMOVE); + } + + if ( _taccess(filename, 0) != 0) { + MySetCursor(IDC_ARROW); + break; + } + + LVITEM lvi; + lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; + lvi.iSubItem = 0; + lvi.iItem = 0; + int count = (int)_ExtractIconEx(filename, -1, 16, 16, NULL, LR_DEFAULTCOLOR); + for (int i = 0; i < count; lvi.iItem++, i++) { + mir_sntprintf(caption, SIZEOF(caption), _T("%d"), i+1); + lvi.pszText = caption; + + HICON hIcon; + _ExtractIconEx(filename, i, 16, 16, &hIcon, LR_DEFAULTCOLOR); + lvi.iImage = ImageList_AddIcon(hIml, hIcon); + DestroyIcon(hIcon); + lvi.lParam = i; + ListView_InsertItem(hPreview, &lvi); + } + MySetCursor(IDC_ARROW); + } + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BROWSE: + { + TCHAR str[MAX_PATH], *file; + GetDlgItemText(hwndDlg, IDC_ICONSET, str, SIZEOF(str)); + if ( !(file = OpenFileDlg(GetParent(hwndDlg), str, TRUE))) + break; + SetDlgItemText(hwndDlg, IDC_ICONSET, file); + SAFE_FREE((void**)&file); + } + break; + + case IDC_GETMORE: + OpenIconsPage(); + break; + + case IDC_ICONSET: + if (HIWORD(wParam) == EN_CHANGE) + SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, 0); + break; + } + break; + + case WM_MOUSEMOVE: + if (dragging) { + LVHITTESTINFO lvhti; + int onItem=0; + HWND hwndOver; + RECT rc; + POINT ptDrag; + HWND hPPreview = GetDlgItem(hwndParent, IDC_PREVIEW); + + lvhti.pt.x = (short)LOWORD(lParam); lvhti.pt.y = (short)HIWORD(lParam); + ClientToScreen(hwndDlg, &lvhti.pt); + hwndOver = WindowFromPoint(lvhti.pt); + GetWindowRect(hwndOver, &rc); + ptDrag.x = lvhti.pt.x - rc.left; ptDrag.y = lvhti.pt.y - rc.top; + if (hwndOver != hwndDragOver) { + ImageList_DragLeave(hwndDragOver); + hwndDragOver = hwndOver; + ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); + } + + ImageList_DragMove(ptDrag.x, ptDrag.y); + if (hwndOver == hPPreview) { + ScreenToClient(hPPreview, &lvhti.pt); + + if (ListView_HitTest(hPPreview, &lvhti) != -1) { + if (lvhti.iItem != dropHiLite) { + ImageList_DragLeave(hwndDragOver); + if (dropHiLite != -1) + ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED); + dropHiLite = lvhti.iItem; + ListView_SetItemState(hPPreview, dropHiLite, LVIS_DROPHILITED, LVIS_DROPHILITED); + UpdateWindow(hPPreview); + ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); + } + onItem = 1; + } } + + if ( !onItem && dropHiLite != -1) { + ImageList_DragLeave(hwndDragOver); + ListView_SetItemState(hPPreview, dropHiLite, 0, LVIS_DROPHILITED); + UpdateWindow(hPPreview); + ImageList_DragEnter(hwndDragOver, ptDrag.x, ptDrag.y); + dropHiLite = -1; + } + MySetCursor(onItem ? IDC_ARROW : IDC_NO); + } + break; + + case WM_LBUTTONUP: + if (dragging) { + ReleaseCapture(); + ImageList_EndDrag(); + dragging = 0; + if (dropHiLite != -1) { + TCHAR path[MAX_PATH], fullPath[MAX_PATH], filename[MAX_PATH]; + LVITEM lvi; + + GetDlgItemText(hwndDlg, IDC_ICONSET, fullPath, SIZEOF(fullPath)); + CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)fullPath, (LPARAM)filename); + lvi.mask=LVIF_PARAM; + lvi.iItem = dragItem; lvi.iSubItem = 0; + ListView_GetItem(hPreview, &lvi); + mir_sntprintf(path, MAX_PATH, _T("%s,%d"), filename, (int)lvi.lParam); + SendMessage(hwndParent, DM_CHANGEICON, dropHiLite, (LPARAM)path); + ListView_SetItemState(GetDlgItem(hwndParent, IDC_PREVIEW), dropHiLite, 0, LVIS_DROPHILITED); + } } + break; + + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->idFrom) { + case IDC_PREVIEW: + switch (((LPNMHDR)lParam)->code) { + case LVN_BEGINDRAG: + SetCapture(hwndDlg); + dragging = 1; + dragItem = ((LPNMLISTVIEW)lParam)->iItem; + dropHiLite = -1; + ImageList_BeginDrag(ListView_GetImageList(hPreview, LVSIL_NORMAL), dragItem, GetSystemMetrics(SM_CXICON)/2, GetSystemMetrics(SM_CYICON)/2); + { + POINT pt; + RECT rc; + + GetCursorPos(&pt); + GetWindowRect(hwndDlg, &rc); + ImageList_DragEnter(hwndDlg, pt.x - rc.left, pt.y - rc.top); + hwndDragOver = hwndDlg; + } + break; + } + break; + } + break; + + case WM_SIZE: // make the dlg resizeable + if ( !IsIconic(hwndDlg)) { + UTILRESIZEDIALOG urd = {0}; + urd.cbSize = sizeof(urd); + urd.hInstance = hMirandaInst; + urd.hwndDlg = hwndDlg; + urd.lParam = 0; // user-defined + urd.lpTemplate = MAKEINTRESOURCEA(IDD_ICOLIB_IMPORT); + urd.pfnResizer = IconDlg_Resize; + CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); + } + break; + + case WM_CLOSE: + DestroyWindow(hwndDlg); + EnableWindow(GetDlgItem(hwndParent, IDC_IMPORT), TRUE); + break; + + } + + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// IcoLib options window procedure + +static int CALLBACK DoSortIconsFunc(LPARAM lParam1, LPARAM lParam2, LPARAM) +{ return lstrcmpi(iconList[lParam1]->getDescr(), iconList[lParam2]->getDescr()); +} + +static int CALLBACK DoSortIconsFuncByOrder(LPARAM lParam1, LPARAM lParam2, LPARAM) +{ return iconList[lParam1]->orderID - iconList[lParam2]->orderID; +} + +static void SaveCollapseState(HWND hwndTree) +{ + HTREEITEM hti = TreeView_GetRoot(hwndTree); + while (hti != NULL) { + TVITEM tvi; + tvi.mask = TVIF_STATE | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM; + tvi.hItem = hti; + tvi.stateMask = (DWORD)-1; + TreeView_GetItem(hwndTree, &tvi); + + if (tvi.cChildren > 0) { + TreeItem *treeItem = (TreeItem *)tvi.lParam; + if (tvi.state & TVIS_EXPANDED) + DBWriteContactSettingByte(NULL, "SkinIconsUI", treeItem->paramName, TVIS_EXPANDED); + else + DBWriteContactSettingByte(NULL, "SkinIconsUI", treeItem->paramName, 0); + } + + HTREEITEM ht = TreeView_GetChild(hwndTree, hti); + if (ht == NULL) { + ht = TreeView_GetNextSibling(hwndTree, hti); + while (ht == NULL) { + hti = TreeView_GetParent(hwndTree, hti); + if (hti == NULL) break; + ht = TreeView_GetNextSibling(hwndTree, hti); + } + } + + hti = ht; + } +} + +INT_PTR CALLBACK DlgProcIcoLibOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + struct IcoLibOptsData *dat; + static HTREEITEM prevItem = 0; + static HWND hPreview = NULL; + + dat = (struct IcoLibOptsData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + hPreview = GetDlgItem(hwndDlg, IDC_PREVIEW); + dat = (struct IcoLibOptsData*)mir_alloc(sizeof(struct IcoLibOptsData)); + dat->hwndIndex = NULL; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); + // + // Reset temporary data & upload sections list + // + EnterCriticalSection(&csIconList); + { + int indx; + for (indx = 0; indx < iconList.getCount(); indx++) { + iconList[indx]->temp_file = NULL; + iconList[indx]->temp_icon = NULL; + iconList[indx]->temp_reset = FALSE; + } + bNeedRebuild = FALSE; + } + LeaveCriticalSection(&csIconList); + // + // Setup preview listview + // + ListView_SetUnicodeFormat(hPreview, TRUE); + ListView_SetExtendedListViewStyleEx(hPreview, LVS_EX_INFOTIP, LVS_EX_INFOTIP); + ListView_SetImageList(hPreview, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32|ILC_MASK, 0, 30), LVSIL_NORMAL); + ListView_SetIconSpacing(hPreview, 56, 67); + + SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); + return TRUE; + + case DM_REBUILD_CTREE: + { + HWND hwndTree = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); + int indx; + TCHAR itemName[1024]; + HTREEITEM hSection; + + if ( !hwndTree) break; + + TreeView_SelectItem(hwndTree, NULL); + TreeView_DeleteAllItems(hwndTree); + + for (indx = 0; indx < sectionList.getCount(); indx++) { + TCHAR* sectionName; + int sectionLevel = 0; + + hSection = NULL; + lstrcpy(itemName, sectionList[indx]->name); + sectionName = itemName; + + while (sectionName) { + // allow multi-level tree + TCHAR* pItemName = sectionName; + HTREEITEM hItem; + + if (sectionName = _tcschr(sectionName, '/')) { + // one level deeper + *sectionName = 0; + } + + pItemName = TranslateTS(pItemName); + hItem = FindNamedTreeItemAt(hwndTree, hSection, pItemName); + if ( !sectionName || !hItem) { + if ( !hItem) { + TVINSERTSTRUCT tvis = {0}; + TreeItem *treeItem = (TreeItem *)mir_alloc(sizeof(TreeItem)); + treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, sectionName ? 0 : SECTIONPARAM_HAVEPAGE); + treeItem->paramName = mir_t2a(itemName); + + tvis.hParent = hSection; + tvis.hInsertAfter = TVI_SORT; + tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE; + tvis.item.pszText = pItemName; + tvis.item.lParam = (LPARAM) treeItem; + + tvis.item.state = tvis.item.stateMask = DBGetContactSettingByte(NULL, "SkinIconsUI", treeItem->paramName, TVIS_EXPANDED); + hItem = TreeView_InsertItem(hwndTree, &tvis); + } + else { + TVITEM tvi = {0}; + tvi.hItem = hItem; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + TreeView_GetItem(hwndTree, &tvi); + TreeItem *treeItem = (TreeItem *)tvi.lParam; + treeItem->value = SECTIONPARAM_MAKE(indx, sectionLevel, SECTIONPARAM_HAVEPAGE); + } } + + if (sectionName) { + *sectionName = '/'; + sectionName++; + } + sectionLevel++; + + hSection = hItem; + } + } + + ShowWindow(hwndTree, SW_SHOW); + + TreeView_SelectItem(hwndTree, FindNamedTreeItemAt(hwndTree, 0, NULL)); + } + break; + + // Rebuild preview to new section + case DM_REBUILDICONSPREVIEW: + { + SectionItem* sectionActive = (SectionItem*)lParam; + EnableWindow(hPreview, sectionActive != NULL); + + ListView_DeleteAllItems(hPreview); + HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); + ImageList_RemoveAll(hIml); + + if (sectionActive == NULL) + break; + + LVITEM lvi = {0}; + lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + + EnterCriticalSection(&csIconList); + + for (int indx = 0; indx < iconList.getCount(); indx++) { + IconItem *item = iconList[indx]; + if (item->section == sectionActive) { + lvi.pszText = item->getDescr(); + HICON hIcon = item->temp_icon; + if (!hIcon) + hIcon = IconItem_GetIcon_Preview(item); + lvi.iImage = ImageList_AddIcon(hIml, hIcon); + lvi.lParam = indx; + ListView_InsertItem(hPreview, &lvi); + if (hIcon != item->temp_icon) + SafeDestroyIcon(&hIcon); + } + } + + LeaveCriticalSection(&csIconList); + + if (sectionActive->flags & SIDF_SORTED) + ListView_SortItems(hPreview, DoSortIconsFunc, 0); + else + ListView_SortItems(hPreview, DoSortIconsFuncByOrder, 0); + } + break; + + // Refresh preview to new section + case DM_UPDATEICONSPREVIEW: + { + LVITEM lvi = {0}; + HICON hIcon; + int indx, count; + HIMAGELIST hIml = ListView_GetImageList(hPreview, LVSIL_NORMAL); + + lvi.mask = LVIF_IMAGE|LVIF_PARAM; + count = ListView_GetItemCount(hPreview); + + for (indx = 0; indx < count; indx++) { + lvi.iItem = indx; + ListView_GetItem(hPreview, &lvi); + EnterCriticalSection(&csIconList); + hIcon = iconList[lvi.lParam]->temp_icon; + if ( !hIcon) + hIcon = IconItem_GetIcon_Preview(iconList[lvi.lParam]); + LeaveCriticalSection(&csIconList); + + if (hIcon) + ImageList_ReplaceIcon(hIml, lvi.iImage, hIcon); + if (hIcon != iconList[lvi.lParam]->temp_icon) SafeDestroyIcon(&hIcon); + } + ListView_RedrawItems(hPreview, 0, count); + } + break; + + // Temporary change icon - only inside options dialog + case DM_CHANGEICON: + { + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + lvi.iItem = wParam; + ListView_GetItem(hPreview, &lvi); + + EnterCriticalSection(&csIconList); + IconItem *item = iconList[ lvi.lParam ]; + + SAFE_FREE((void**)&item->temp_file); + SafeDestroyIcon(&item->temp_icon); + + TCHAR *path = (TCHAR*)lParam; + item->temp_file = mir_tstrdup(path); + item->temp_icon = (HICON)ExtractIconFromPath(path, item->cx, item->cy); + item->temp_reset = FALSE; + + LeaveCriticalSection(&csIconList); + DoOptionsChanged(hwndDlg); + } + break; + + case WM_COMMAND: + if (LOWORD(wParam) == IDC_IMPORT) { + dat->hwndIndex = CreateDialogParam(hMirandaInst, MAKEINTRESOURCE(IDD_ICOLIB_IMPORT), GetParent(hwndDlg), DlgProcIconImport, (LPARAM)hwndDlg); + EnableWindow((HWND)lParam, FALSE); + } + else if (LOWORD(wParam) == IDC_GETMORE) { + OpenIconsPage(); + break; + } + else if (LOWORD(wParam) == IDC_LOADICONS) { + TCHAR filetmp[1] = {0}; + TCHAR *file; + + if (file = OpenFileDlg(hwndDlg, filetmp, FALSE)) { + HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); + TCHAR filename[ MAX_PATH ]; + + CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)file, (LPARAM)filename); + SAFE_FREE((void**)&file); + + MySetCursor(IDC_WAIT); + LoadSubIcons(htv, filename, TreeView_GetSelection(htv)); + MySetCursor(IDC_ARROW); + + DoOptionsChanged(hwndDlg); + } } + break; + + case WM_CONTEXTMENU: + if ((HWND)wParam == hPreview) { + UINT count = ListView_GetSelectedCount(hPreview); + + if (count > 0) { + int cmd = OpenPopupMenu(hwndDlg); + switch(cmd) { + case ID_CANCELCHANGE: + case ID_RESET: + { + LVITEM lvi = {0}; + int itemIndx = -1; + + while ((itemIndx = ListView_GetNextItem(hPreview, itemIndx, LVNI_SELECTED)) != -1) { + lvi.mask = LVIF_PARAM; + lvi.iItem = itemIndx; //lvhti.iItem; + ListView_GetItem(hPreview, &lvi); + + UndoChanges(lvi.lParam, cmd); + } + + DoOptionsChanged(hwndDlg); + break; + } } } + } + else { + HWND htv = GetDlgItem(hwndDlg, IDC_CATEGORYLIST); + if ((HWND)wParam == htv) { + int cmd = OpenPopupMenu(hwndDlg); + + switch(cmd) { + case ID_CANCELCHANGE: + case ID_RESET: + UndoSubItemChanges(htv, TreeView_GetSelection(htv), cmd); + DoOptionsChanged(hwndDlg); + break; + } } } + break; + + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch(((LPNMHDR)lParam)->code) { + case PSN_APPLY: + { + EnterCriticalSection(&csIconList); + + for (int indx = 0; indx < iconList.getCount(); indx++) { + IconItem *item = iconList[indx]; + if (item->temp_reset) { + DBDeleteContactSetting(NULL, "SkinIcons", item->name); + if (item->source_small != item->default_icon) { + IconSourceItem_Release(&item->source_small); + } + } + else if (item->temp_file) { + DBWriteContactSettingTString(NULL, "SkinIcons", item->name, item->temp_file); + IconSourceItem_Release(&item->source_small); + SafeDestroyIcon(&item->temp_icon); + } + } + LeaveCriticalSection(&csIconList); + + DoIconsChanged(hwndDlg); + return TRUE; + } + } + break; + + case IDC_PREVIEW: + if (((LPNMHDR)lParam)->code == LVN_GETINFOTIP) { + IconItem *item; + NMLVGETINFOTIP *pInfoTip = (NMLVGETINFOTIP *)lParam; + LVITEM lvi; + lvi.mask = LVIF_PARAM; + lvi.iItem = pInfoTip->iItem; + ListView_GetItem(pInfoTip->hdr.hwndFrom, &lvi); + + if (lvi.lParam < iconList.getCount()) { + item = iconList[lvi.lParam]; + if (item->temp_file) + _tcsncpy(pInfoTip->pszText, item->temp_file, pInfoTip->cchTextMax); + else if (item->default_file) + mir_sntprintf(pInfoTip->pszText, pInfoTip->cchTextMax, _T("%s, %d"), item->default_file, item->default_indx); + } + } + if (bNeedRebuild) { + EnterCriticalSection(&csIconList); + bNeedRebuild = FALSE; + LeaveCriticalSection(&csIconList); + SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); + } + break; + + case IDC_CATEGORYLIST: + switch(((NMHDR*)lParam)->code) { + case TVN_SELCHANGEDA: // !!!! This needs to be here - both !! + case TVN_SELCHANGEDW: + { + NMTREEVIEW *pnmtv = (NMTREEVIEW*)lParam; + TVITEM tvi = pnmtv->itemNew; + TreeItem *treeItem = (TreeItem *)tvi.lParam; + if (treeItem) + SendMessage(hwndDlg, DM_REBUILDICONSPREVIEW, 0, (LPARAM)( + (SECTIONPARAM_FLAGS(treeItem->value)&SECTIONPARAM_HAVEPAGE)? + sectionList[ SECTIONPARAM_INDEX(treeItem->value) ] : NULL)); + break; + } + case TVN_DELETEITEMA: // no idea why both TVN_SELCHANGEDA/W should be there but let's keep this both too... + case TVN_DELETEITEMW: + { + TreeItem *treeItem = (TreeItem *)(((LPNMTREEVIEW)lParam)->itemOld.lParam); + if (treeItem) { + mir_free(treeItem->paramName); + mir_free(treeItem); + } + break; + } + } + if (bNeedRebuild) { + EnterCriticalSection(&csIconList); + bNeedRebuild = FALSE; + LeaveCriticalSection(&csIconList); + SendMessage(hwndDlg, DM_REBUILD_CTREE, 0, 0); + } } + break; + + case WM_DESTROY: + SaveCollapseState(GetDlgItem(hwndDlg, IDC_CATEGORYLIST)); + DestroyWindow(dat->hwndIndex); + + EnterCriticalSection(&csIconList); + { + for (int indx = 0; indx < iconList.getCount(); indx++) { + IconItem *item = iconList[indx]; + + SAFE_FREE((void**)&item->temp_file); + SafeDestroyIcon(&item->temp_icon); + } + } + LeaveCriticalSection(&csIconList); + + SAFE_FREE((void**)&dat); + break; + } + + return FALSE; +} + +static UINT iconsExpertOnlyControls[]={IDC_IMPORT}; + +int SkinOptionsInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = {0}; + odp.cbSize = sizeof(odp); + odp.hInstance = hMirandaInst; + odp.flags = ODPF_BOLDGROUPS; + odp.position = -180000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICOLIB); + odp.pszTitle = LPGEN("Icons"); + odp.pszGroup = LPGEN("Customize"); + odp.pfnDlgProc = DlgProcIcoLibOpts; + odp.expertOnlyControls = iconsExpertOnlyControls; + odp.nExpertOnlyControls = SIZEOF(iconsExpertOnlyControls); + Options_AddPage(wParam, &odp); + return 0; +} diff --git a/src/modules/skin/skinicons.cpp b/src/modules/skin/skinicons.cpp index 777cc19757..24138e0000 100644 --- a/src/modules/skin/skinicons.cpp +++ b/src/modules/skin/skinicons.cpp @@ -314,7 +314,7 @@ HICON LoadSkinProtoIcon(const char* szProto, int status, bool big) sid.pszName = iconName; sid.ptszDescription = cli.pfnGetStatusModeDescription(statusIcons[i].id, 0); sid.iDefaultIndex = statusIcons[i].resource_id; - IcoLib_AddNewIcon(&sid); + IcoLib_AddNewIcon(0, &sid); } } } } // format: core_status_%s%d @@ -364,12 +364,11 @@ static void convertOneProtocol(char* moduleName, char* iconName) { char* pm = moduleName + strlen(moduleName); char* pi = iconName + strlen(iconName); - DBVARIANT dbv; - int i; - for (i = 0; i < SIZEOF(statusIcons); i++) { + for (int i = 0; i < SIZEOF(statusIcons); i++) { _itoa(statusIcons[i].id, pm, 10); + DBVARIANT dbv; if ( !DBGetContactSettingTString(NULL, "Icons", moduleName, &dbv)) { _itoa(i, pi, 10); @@ -471,7 +470,7 @@ int LoadSkinIcons(void) sid.pszSection = mainIcons[i].section == NULL ? "Main Icons" : (char*)mainIcons[i].section; sid.pszDescription = (char*)mainIcons[i].description; sid.iDefaultIndex = mainIcons[i].resource_id; - hMainIcons[i] = IcoLib_AddNewIcon(&sid); + hMainIcons[i] = IcoLib_AddNewIcon(0, &sid); } // // Add global icons to list @@ -485,7 +484,7 @@ int LoadSkinIcons(void) sid.pszName = iconName; sid.pszDescription = (char*)statusIcons[i].description; sid.iDefaultIndex = statusIcons[i].resource_id; - hStatusIcons[i] = IcoLib_AddNewIcon(&sid); + hStatusIcons[i] = IcoLib_AddNewIcon(0, &sid); } return 0; } -- cgit v1.2.3