summaryrefslogtreecommitdiff
path: root/src/modules/icolib
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/icolib')
-rw-r--r--src/modules/icolib/IcoLib.h61
-rw-r--r--src/modules/icolib/skin2icons.cpp1136
-rw-r--r--src/modules/icolib/skin2opts.cpp1051
3 files changed, 1133 insertions, 1115 deletions
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<IconItem> iconList;
+extern LIST<SectionItem> 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<SectionItem> sectionList(20, sttCompareSections);
+LIST<SectionItem> 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<IconItem> iconList(20, sttCompareIcons);
+LIST<IconItem> 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);
@@ -724,46 +668,6 @@ HICON IconItem_GetIcon(IconItem* item, bool big)
}
/////////////////////////////////////////////////////////////////////////////////////////
-// 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
// wParam: PLOADIMAGEPARAM or NULL.
@@ -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;
+}