winamp/Src/Plugins/Library/ml_devices/navigation.cpp

1073 lines
23 KiB
C++
Raw Permalink Normal View History

2024-09-24 12:54:57 +00:00
#include "main.h"
#include "./navigation.h"
#include <strsafe.h>
#define DEVICES_NAVITEM_PREFIX L"ml_devices_"
static HNAVITEM navigationRoot = NULL;
static size_t deviceHandler = 0;
static HNAVITEM
NavigationItem_Insert(HNAVITEM parent,
HNAVITEM insertAfter,
unsigned int mask,
int itemId,
const wchar_t *name,
const wchar_t *displayName,
unsigned int style,
int image,
LPARAM param)
{
NAVITEM *item;
NAVINSERTSTRUCT nis = {0};
nis.hInsertAfter = insertAfter;
nis.hParent = parent;
item = &nis.item;
item->cbSize = sizeof(NAVITEM);
item->id = itemId;
if (0 != (NIMF_IMAGE & mask))
mask |= NIMF_IMAGESEL;
item->mask = mask;
item->pszText = (wchar_t*)displayName;
item->pszInvariant = (wchar_t*)name;
item->style = style;
item->styleMask = style;
item->iImage = image;
item->iSelectedImage = image;
item->lParam = param;
if (!wcsnicmp(L"ml_devices_all_sources", item->pszInvariant, 22))
{
// and this will allow us to make the cloud library
// root do a web page or a sources view as needed...
return NULL;
}
return MLNavCtrl_InsertItem(Plugin_GetLibraryWindow(), &nis);
}
static BOOL
NavigationItem_Delete(HNAVITEM item)
{
return MLNavCtrl_DeleteItem(Plugin_GetLibraryWindow(), item);
}
static HNAVITEM
NavigationItem_GetFromMessage(INT msg, INT_PTR param)
{
return (msg < ML_MSG_NAVIGATION_FIRST) ?
MLNavCtrl_FindItemById(Plugin_GetLibraryWindow(), param) :
(HNAVITEM)param;
}
static HNAVITEM
NavigationItem_Find(HNAVITEM root, const wchar_t *name, BOOL allow_root = 0)
{
NAVCTRLFINDPARAMS find = {0};
HNAVITEM item;
HWND libraryWindow;
if (NULL == name)
return NULL;
libraryWindow = Plugin_GetLibraryWindow();
if (NULL == libraryWindow)
return NULL;
find.pszName = (wchar_t*)name;
find.cchLength = -1;
find.compFlags = NICF_INVARIANT;
find.fFullNameSearch = FALSE;
item = MLNavCtrl_FindItemByName(libraryWindow, &find);
if (NULL == item)
return NULL;
if (!allow_root)
{
// if allowed then we can look for root level items which
// is really for getting 'cloud' devices to another group
if (NULL != root &&
root != MLNavItem_GetParent(libraryWindow, item))
{
item = NULL;
}
}
return item;
}
static wchar_t *
NavigationItem_GetNameFromDeviceName(wchar_t *buffer, size_t bufferMax, const char *name)
{
wchar_t *cursor;
size_t length;
BOOL allocated;
if (NULL == name || '\0' == *name)
return NULL;
length = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
if (ARRAYSIZE(DEVICES_NAVITEM_PREFIX) > bufferMax ||
length > (bufferMax - (ARRAYSIZE(DEVICES_NAVITEM_PREFIX) - 1)))
{
bufferMax = length + ARRAYSIZE(DEVICES_NAVITEM_PREFIX) - 1;
buffer = String_Malloc(bufferMax);
if (NULL == buffer)
return NULL;
allocated = TRUE;
}
else
allocated = FALSE;
if (FAILED(StringCchCopyEx(buffer, bufferMax, DEVICES_NAVITEM_PREFIX, &cursor, &length, 0)) ||
0 == MultiByteToWideChar(CP_UTF8, 0, name, -1, cursor, (int)length))
{
if (FALSE != allocated)
String_Free(buffer);
return NULL;
}
return buffer;
}
static HNAVITEM
NavigationItem_FindFromDeviceName(HNAVITEM root, const char *name)
{
wchar_t buffer[1], *itemName;
HNAVITEM item;
if (NULL == root)
return NULL;
itemName = NavigationItem_GetNameFromDeviceName(buffer, ARRAYSIZE(buffer), name);
if (NULL == itemName)
return NULL;
item = NavigationItem_Find(root, itemName);
if (itemName != buffer)
String_Free(itemName);
return item;
}
static HNAVITEM
NavigationItem_FindFromDevice(HNAVITEM root, ifc_device *device)
{
if (NULL == device)
return NULL;
return NavigationItem_FindFromDeviceName(root, device->GetName());
}
static BOOL
NavigationItem_DisplayDeviceMenu(HNAVITEM item, const char *deviceName, HWND hostWindow, POINT pt)
{
HMENU menu;
ifc_device *device;
unsigned int commandId;
BOOL succeeded;
HWND libraryWindow;
libraryWindow = Plugin_GetLibraryWindow();
if (NULL == item|| NULL == deviceName)
return FALSE;
if (NULL == WASABI_API_DEVICES ||
S_OK != WASABI_API_DEVICES->DeviceFind(deviceName, &device))
{
return FALSE;
}
menu = CreatePopupMenu();
if (NULL != menu)
{
if (0 == Menu_InsertDeviceItems(menu, 0, 100, device, DeviceCommandContext_NavigationMenu))
{
DestroyMenu(menu);
menu = NULL;
}
}
device->Release();
if (NULL == menu)
return FALSE;
succeeded = FALSE;
if (item == MLNavCtrl_GetSelection(libraryWindow))
{
commandId = Menu_FindItemByAnsiStringData(menu, "view_open");
if ((unsigned int)-1 != commandId)
EnableMenuItem(menu, commandId, MF_BYCOMMAND | MF_DISABLED);
}
commandId = Menu_TrackPopup(Plugin_GetLibraryWindow(), menu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_RETURNCMD,
pt.x, pt.y, hostWindow, NULL);
if (0 != commandId)
{
const char *command;
command = (const char*)Menu_GetItemData(menu, commandId, FALSE);
if (NULL != command)
{
if (NULL != WASABI_API_DEVICES &&
S_OK == WASABI_API_DEVICES->DeviceFind(deviceName, &device))
{
BOOL commandProcessed;
commandProcessed = FALSE;
if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, 0, command, -1, "view_open", -1))
{
succeeded = MLNavItem_Select(libraryWindow, item);
commandProcessed = succeeded;
}
else if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, 0, command, -1, "rename", -1))
{
succeeded = MLNavItem_EditTitle(libraryWindow, item);
commandProcessed = succeeded;
}
if (FALSE == commandProcessed &&
SUCCEEDED(device->SendCommand(command, hostWindow, 0)))
{
succeeded = TRUE;
}
device->Release();
}
}
}
else
{
if (ERROR_SUCCESS == GetLastError())
succeeded = TRUE;
}
Menu_FreeItemData(menu, 0, -1);
return succeeded;
}
static BOOL
NavigationItem_DisplayRootMenu(HNAVITEM item, HWND hostWindow, POINT pt)
{
HMENU pluginMenu, menu;
BOOL succeeded;
if (NULL == item)
return FALSE;
pluginMenu = Plugin_LoadMenu();
if (NULL == pluginMenu)
return FALSE;
succeeded = FALSE;
menu = GetSubMenu(pluginMenu, 0);
if (NULL != menu)
{
HWND libraryWindow;
HNAVITEM selectedItem;
libraryWindow = Plugin_GetLibraryWindow();
selectedItem = MLNavCtrl_GetSelection(libraryWindow);
EnableMenuItem(menu, ID_VIEW_OPEN, MF_BYCOMMAND | ((item != selectedItem) ? MF_ENABLED : MF_DISABLED));
SetMenuDefaultItem(menu, ID_VIEW_OPEN, FALSE);
unsigned int commandId = Menu_TrackPopup(Plugin_GetLibraryWindow(), menu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_RETURNCMD,
pt.x, pt.y, hostWindow, NULL);
if (0 != commandId)
{
switch(commandId)
{
case ID_VIEW_OPEN:
MLNavItem_Select(libraryWindow, item);
break;
case ID_DISCOVERY_BEGIN:
Plugin_BeginDiscovery();
break;
case ID_PLUGIN_HELP:
Plugin_ShowHelp();
break;
}
}
else
{
if (ERROR_SUCCESS == GetLastError())
succeeded = TRUE;
}
}
DestroyMenu(pluginMenu);
return succeeded;
}
static BOOL
Navigation_GetDeviceTitle(ifc_device *device, wchar_t *buffer, size_t bufferMax)
{
size_t read, write;
if (NULL == device ||
FAILED(device->GetDisplayName(buffer, bufferMax)))
{
return FALSE;
}
for(read = 0, write = 0;; read++)
{
if (read == bufferMax)
return FALSE;
if (L'\r' == buffer[read])
continue;
if (L'\n' == buffer[read] ||
L'\t' == buffer[read] ||
L'\b' == buffer[read])
{
buffer[write] = L' ';
}
buffer[write] = buffer[read];
if (L'\0' == buffer[read])
break;
write++;
}
return TRUE;
}
static BOOL
Navigation_DeviceAdd(HNAVITEM root, ifc_device *device)
{
HNAVITEM item, insertAfter = NCI_LAST;
wchar_t nameBuffer[256] = {0}, *itemName;
wchar_t title[512] = {0};
int iconIndex;
if (NULL == device)
return FALSE;
itemName = NavigationItem_GetNameFromDeviceName(nameBuffer, ARRAYSIZE(nameBuffer), device->GetName());
if (NULL == itemName)
return FALSE;
if (NULL != NavigationItem_Find(root, itemName))
{
if (itemName != nameBuffer)
String_Free(itemName);
return FALSE;
}
if (FALSE == Navigation_GetDeviceTitle(device, title, ARRAYSIZE(title)))
title[0] = L'\0';
iconIndex = NavigationIcons_GetDeviceIconIndex(device);
// filter the cloud devices to their own group
if (!lstrcmpiA(device->GetConnection(), "cloud"))
{
HNAVITEM cloud = NavigationItem_Find(navigationRoot, L"cloud_sources", TRUE);
if (cloud != NULL)
{
root = cloud;
HNAVITEM transfers = NavigationItem_Find(0, L"cloud_transfers", TRUE);
// to maintain some specific orders, we need to alter the insert position
if (!wcsnicmp(L"ml_devices_hss", itemName, 14))
{
insertAfter = transfers;
if (!insertAfter) insertAfter = NCI_LAST;
}
else if (!wcsnicmp(L"ml_devices_local_desktop", itemName, 24))
{
insertAfter = NavigationItem_Find(0, L"ml_devices_hss", TRUE);
if (!insertAfter) insertAfter = NCI_LAST;
}
// when adding children, change from the cloud source to the open/closed arrow
HWND libraryWindow = Plugin_GetLibraryWindow();
if (NULL != libraryWindow && transfers)
{
NAVITEM itemInfo = {0};
itemInfo.hItem = cloud;
itemInfo.cbSize = sizeof(itemInfo);
itemInfo.mask = NIMF_IMAGE | NIMF_IMAGESEL;
itemInfo.iImage = itemInfo.iSelectedImage = -1;
MLNavItem_SetInfo(libraryWindow, &itemInfo);
}
}
}
item = NavigationItem_Insert(root, insertAfter,
NIMF_TEXT | NIMF_TEXTINVARIANT | NIMF_IMAGE | NIMF_IMAGESEL | NIMF_STYLE,
0, itemName, title, NIS_ALLOWEDIT, iconIndex, 0L);
if (NULL == item)
NavigationIcons_ReleaseIconIndex(iconIndex);
if (itemName != nameBuffer)
String_Free(itemName);
if (NULL == item)
return FALSE;
device->SetNavigationItem(item);
return TRUE;
}
static BOOL
Navigation_DeviceRemove(HNAVITEM root, ifc_device *device)
{
HNAVITEM item;
item = NavigationItem_FindFromDevice(root, device);
if (NULL == item)
return FALSE;
return NavigationItem_Delete(item);
}
static BOOL
Navigation_DeviceTitleChanged(HNAVITEM root, ifc_device *device)
{
NAVITEM itemInfo;
wchar_t buffer[1024] = {0};
itemInfo.hItem = NavigationItem_FindFromDevice(root, device);
if (NULL == itemInfo.hItem)
return FALSE;
if (FALSE == Navigation_GetDeviceTitle(device, buffer, ARRAYSIZE(buffer)))
return FALSE;
itemInfo.cbSize = sizeof(itemInfo);
itemInfo.pszText = buffer;
itemInfo.cchTextMax = -1;
itemInfo.mask = NIMF_TEXT;
return MLNavItem_SetInfo(Plugin_GetLibraryWindow(), &itemInfo);
}
static BOOL
Navigation_DeviceIconChanged(HNAVITEM root, ifc_device *device)
{
NAVITEM itemInfo;
int iconIndex;
HWND libraryWindow;
if (NULL == root || NULL == device)
return FALSE;
libraryWindow = Plugin_GetLibraryWindow();
itemInfo.hItem = NavigationItem_FindFromDevice(root, device);
if (NULL == itemInfo.hItem)
return FALSE;
iconIndex = NavigationIcons_GetDeviceIconIndex(device);
itemInfo.cbSize = sizeof(itemInfo);
itemInfo.mask = NIMF_IMAGE;
if (FALSE == MLNavItem_GetInfo(libraryWindow, &itemInfo))
{
NavigationIcons_ReleaseIconIndex(iconIndex);
return FALSE;
}
if (itemInfo.iImage == iconIndex)
{
NavigationIcons_ReleaseIconIndex(iconIndex);
return TRUE;
}
NavigationIcons_ReleaseIconIndex(itemInfo.iImage);
itemInfo.mask = NIMF_IMAGE | NIMF_IMAGESEL;
itemInfo.iImage = iconIndex;
itemInfo.iSelectedImage = iconIndex;
if (FALSE == MLNavItem_SetInfo(libraryWindow, &itemInfo))
{
NavigationIcons_ReleaseIconIndex(iconIndex);
return FALSE;
}
return TRUE;
}
static void
Navigation_AddExistingDevices(HNAVITEM root)
{
ifc_device *device;
ifc_deviceobject *object;
ifc_deviceobjectenum *enumerator;
if (NULL == WASABI_API_DEVICES)
return;
if (FAILED(WASABI_API_DEVICES->DeviceEnumerate(&enumerator)))
return;
while(S_OK == enumerator->Next(&object, 1, NULL))
{
if (SUCCEEDED(object->QueryInterface(IFC_Device, (void**)&device)))
{
if (FALSE == device->GetHidden() &&
FALSE != device->GetAttached())
{
Navigation_DeviceAdd(root, device);
}
device->Release();
}
object->Release();
}
enumerator->Release();
}
static void
Navigation_DeviceCb(ifc_device *device, DeviceEvent eventId, void *user)
{
HNAVITEM rootItem;
rootItem = (HNAVITEM)user;
switch(eventId)
{
case Event_DeviceAdded:
if (FALSE != device->GetAttached())
Navigation_DeviceAdd(rootItem, device);
break;
case Event_DeviceRemoved:
if (FALSE != device->GetAttached())
Navigation_DeviceRemove(rootItem, device);
break;
case Event_DeviceHidden:
if (FALSE != device->GetAttached())
Navigation_DeviceRemove(rootItem, device);
break;
case Event_DeviceShown:
if (FALSE != device->GetAttached())
Navigation_DeviceAdd(rootItem, device);
break;
case Event_DeviceAttached:
Navigation_DeviceAdd(rootItem, device);
break;
case Event_DeviceDetached:
Navigation_DeviceRemove(rootItem, device);
break;
case Event_DeviceDisplayNameChanged:
Navigation_DeviceTitleChanged(rootItem, device);
break;
case Event_DeviceIconChanged:
Navigation_DeviceIconChanged(rootItem, device);
break;
}
}
static BOOL
Navigation_RegisterDeviceHandler(HNAVITEM root)
{
HWND eventRelay;
DeviceEventCallbacks callbacks;
if (0 != deviceHandler)
return FALSE;
eventRelay = Plugin_GetEventRelayWindow();
if (NULL == eventRelay)
return FALSE;
ZeroMemory(&callbacks, sizeof(callbacks));
callbacks.deviceCb = Navigation_DeviceCb;
deviceHandler = EVENTRELAY_REGISTER_HANDLER(eventRelay, &callbacks, root);
return (0 != deviceHandler);
}
BOOL
Navigation_Initialize(void)
{
HWND libraryWindow;
wchar_t buffer[128] = {0};
if (NULL != navigationRoot)
return FALSE;
libraryWindow = Plugin_GetLibraryWindow();
MLNavCtrl_BeginUpdate(libraryWindow, NUF_LOCK_TOP);
WASABI_API_LNGSTRINGW_BUF(IDS_DEVICES_NAVIGATION_NODE, buffer, ARRAYSIZE(buffer));
navigationRoot = NavigationItem_Insert(NULL, NULL,
NIMF_ITEMID | NIMF_TEXT | NIMF_STYLE | NIMF_TEXTINVARIANT |
NIMF_PARAM | NIMF_IMAGE | NIMF_IMAGESEL,
ML_TREEVIEW_ID_DEVICES,
DEVICES_NAVITEM_PREFIX L"root",
buffer,
NIS_HASCHILDREN | NIS_ALLOWCHILDMOVE | NIS_DEFAULTIMAGE,
-1,
-1L);
if (NULL == navigationRoot)
return FALSE;
Navigation_AddExistingDevices(navigationRoot);
Navigation_RegisterDeviceHandler(navigationRoot);
MLNavCtrl_EndUpdate(libraryWindow);
return TRUE;
}
void
Navigation_Uninitialize(void)
{
if (0 != deviceHandler)
{
HWND eventRelay;
eventRelay = Plugin_GetEventRelayWindow();
if (NULL != eventRelay)
{
EVENTRELAY_UNREGISTER_HANDLER(eventRelay, deviceHandler);
}
deviceHandler = NULL;
}
if (NULL != navigationRoot)
{
NavigationItem_Delete(navigationRoot);
navigationRoot = FALSE;
}
NavigationIcons_ClearCache();
}
BOOL
Navigation_SelectDevice(const char *name)
{
HNAVITEM item;
item = NavigationItem_FindFromDeviceName(navigationRoot, name);
if (NULL == item)
return FALSE;
return MLNavItem_Select(Plugin_GetLibraryWindow(), item);
}
BOOL
Navigation_EditDeviceTitle(const char *name)
{
HNAVITEM item;
item = NavigationItem_FindFromDeviceName(navigationRoot, name);
if (NULL == item)
return FALSE;
return MLNavItem_EditTitle(Plugin_GetLibraryWindow(), item);
}
static void
Navigation_DestroyCb()
{
}
static BOOL
NavigationItem_IsMine(HNAVITEM item, ifc_device **device)
{
NAVITEM info;
wchar_t buffer[128] = {0};
INT nameLength;
INT prefixLength;
if (NULL == item)
return FALSE;
if (item == navigationRoot)
{
if (NULL != device)
*device = NULL;
return TRUE;
}
info.cbSize = sizeof(NAVITEM);
info.hItem = item;
info.mask = NIMF_TEXTINVARIANT;
info.cchInvariantMax = ARRAYSIZE(buffer);
info.pszInvariant = buffer;
if (FALSE == MLNavItem_GetInfo(Plugin_GetLibraryWindow(), &info))
return FALSE;
// to maintain some specific orders, we need to alter the insert position
BOOL swappped = FALSE;
if (!wcsnicmp(L"cloud_sources", info.pszInvariant, 13))
{
// and this will allow us to make the cloud library
// root do a web page or a sources view as needed...
lstrcpynW(info.pszInvariant, L"ml_devices_all_sources", ARRAYSIZE(buffer));
swappped = TRUE;
}
nameLength = (NULL != info.pszInvariant) ? lstrlen(info.pszInvariant) : 0;
prefixLength = ARRAYSIZE(DEVICES_NAVITEM_PREFIX) - 1;
if (nameLength <= prefixLength)
return FALSE;
if (CSTR_EQUAL != CompareString(CSTR_INVARIANT, 0,
DEVICES_NAVITEM_PREFIX, prefixLength, info.pszInvariant, prefixLength))
{
return FALSE;
}
if (NULL != device)
{
char name[ARRAYSIZE(buffer)] = {0};
nameLength = WideCharToMultiByte(CP_UTF8, 0,
info.pszInvariant + prefixLength, nameLength - prefixLength,
name, ARRAYSIZE(name), NULL, NULL);
name[nameLength] = '\0';
if (0 == nameLength ||
NULL == WASABI_API_DEVICES ||
S_OK != WASABI_API_DEVICES->DeviceFind(name, device))
{
*device = NULL;
if (swappped) return FALSE;
}
}
return TRUE;
}
static HWND
Navigation_CreateViewErrorWidget(HWND hostWindow, void *user)
{
return InfoWidget_CreateWindow(WIDGET_TYPE_VIEW_ERROR,
MAKEINTRESOURCE(IDS_INFOWIDGET_TITLE),
MAKEINTRESOURCE(IDS_CREATE_DEVICE_VIEW_FAILED),
NULL,
hostWindow, 0, 0, 0, 0, FALSE, 0);
}
static HWND
NavigationItem_CreateViewCb(HNAVITEM item, HWND parentWindow)
{
HWND hwnd;
ifc_device *device;
if (NULL == item ||
FALSE == NavigationItem_IsMine(item, &device))
return NULL;
if (NULL != device)
{
hwnd = device->CreateView(parentWindow);
device->Release();
if (NULL == hwnd)
{
hwnd = WidgetHost_Create(0, 0, 0, 0, 0, parentWindow, Navigation_CreateViewErrorWidget, NULL);
}
}
else
{
hwnd = ManagerView_CreateWindow(parentWindow);
}
return hwnd;
}
static BOOL
NavigationItem_ShowContextMenuCb(HNAVITEM item, HWND hostWindow, POINTS pts)
{
POINT pt;
ifc_device *device;
if (NULL == item ||
FALSE == NavigationItem_IsMine(item, &device))
return FALSE;
POINTSTOPOINT(pt, pts);
if (item != navigationRoot)
{
if (NULL != device)
{
char *deviceName = AnsiString_Duplicate(device->GetName());
device->Release();
device = NULL;
if (NULL != deviceName)
{
NavigationItem_DisplayDeviceMenu(item, deviceName, hostWindow, pt);
AnsiString_Free(deviceName);
}
}
}
else
{
NavigationItem_DisplayRootMenu(item, hostWindow, pt);
}
if (NULL != device)
device->Release();
return TRUE;
}
static BOOL
NavigationItem_ShowHelpCb(HNAVITEM item, HWND hostWindow, POINTS pts)
{
if (NULL == item ||
FALSE == NavigationItem_IsMine(item, NULL))
{
return FALSE;
}
Plugin_ShowHelp();
return TRUE;
}
static BOOL
NavigationItem_DeleteCb(HNAVITEM item)
{
ifc_device *device;
if (NULL == item ||
FALSE == NavigationItem_IsMine(item, &device))
return FALSE;
if (NULL != device)
{
device->SetNavigationItem(NULL);
device->Release();
}
if (item != navigationRoot)
{
NAVITEM itemInfo;
HWND libraryWindow;
libraryWindow = Plugin_GetLibraryWindow();
itemInfo.cbSize = sizeof(itemInfo);
itemInfo.mask = NIMF_IMAGE;
itemInfo.hItem = item;
if (FALSE != MLNavItem_GetInfo(libraryWindow, &itemInfo) &&
-1 != itemInfo.iImage)
{
NavigationIcons_ReleaseIconIndex(itemInfo.iImage);
}
}
return TRUE;
}
static BOOL
NavigationItem_KeyDownCb(HNAVITEM item, NMTVKEYDOWN *keyData)
{
ifc_device *device;
if (NULL == keyData ||
NULL == item ||
FALSE == NavigationItem_IsMine(item, &device))
{
return FALSE;
}
if (NULL == device)
return TRUE;
switch(keyData->wVKey)
{
case VK_F2:
MLNavItem_EditTitle(Plugin_GetLibraryWindow(), item);
break;
}
device->Release();
return TRUE;
}
static int
NavigationItem_DropTargetCb(HNAVITEM item, unsigned int dataType, void *data)
{
ifc_device *device;
int result;
if (NULL == item ||
FALSE == NavigationItem_IsMine(item, &device))
{
return 0;
}
if (NULL == device)
return -1;
result = -1;
if (NULL == data)
{
if (S_OK == device->GetDropSupported(dataType))
result = 1;
}
else
{
if (SUCCEEDED(device->Drop(data, dataType)))
result = 1;
}
device->Release();
return result;
}
static BOOL
NavigationItem_TitleEditBeginCb(HNAVITEM item)
{ // return TRUE to cancel ediging (only on own items!!!);
ifc_device *device;
BOOL blockEditor;
if (NULL == item ||
FALSE == NavigationItem_IsMine(item, &device))
{
return FALSE;
}
if (NULL == device)
return TRUE;
blockEditor = (FALSE == DeviceCommand_GetEnabled(device, "rename",
DeviceCommandContext_NavigationMenu));
device->Release();
return blockEditor;
}
static BOOL
NavigationItem_TitleEditEndCb(HNAVITEM item, const wchar_t *title)
{
HRESULT hr;
ifc_device *device;
if (NULL == title)
return FALSE;
if (NULL == item ||
FALSE == NavigationItem_IsMine(item, &device) ||
NULL == device)
{
return FALSE;
}
hr = device->SetDisplayName(title);
device->Release();
if (FAILED(hr))
{
HWND libraryWindow;
wchar_t title[256] = {0}, message[1024] = {0};
libraryWindow = Plugin_GetLibraryWindow();
WASABI_API_LNGSTRINGW_BUF(IDS_MESSAGEBOX_TITLE, title, ARRAYSIZE(title));
WASABI_API_LNGSTRINGW_BUF(IDS_MESSAGE_UNABLE_TO_RENAME, message, ARRAYSIZE(message));
MessageBox(libraryWindow, message, title, MB_OK | MB_ICONERROR);
return FALSE;
}
return FALSE;
}
BOOL
Navigation_ProcessMessage(INT msg, INT_PTR param1, INT_PTR param2, INT_PTR param3, INT_PTR *result)
{
if (msg == ML_MSG_NO_CONFIG)
{
*result = TRUE;
return TRUE;
}
if (msg < ML_MSG_TREE_BEGIN || msg > ML_MSG_TREE_END)
return FALSE;
HNAVITEM item;
switch(msg)
{
case ML_MSG_TREE_ONCREATEVIEW:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_CreateViewCb(item, (HWND)param2);
return TRUE;
case ML_MSG_NAVIGATION_CONTEXTMENU:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_ShowContextMenuCb(item, (HWND)param2, MAKEPOINTS(param3));
return TRUE;
case ML_MSG_NAVIGATION_HELP:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_ShowHelpCb(item, (HWND)param2, MAKEPOINTS(param3));
return TRUE;
case ML_MSG_NAVIGATION_ONDELETE:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_DeleteCb(item);
return TRUE;
case ML_MSG_TREE_ONKEYDOWN:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_KeyDownCb(item, (NMTVKEYDOWN*)param2);
return TRUE;
case ML_MSG_TREE_ONDROPTARGET:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_DropTargetCb(item, (unsigned int)param2, (void*)param3);
return TRUE;
case ML_MSG_NAVIGATION_ONBEGINTITLEEDIT:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_TitleEditBeginCb(item);
return TRUE;
case ML_MSG_NAVIGATION_ONENDTITLEEDIT:
item = NavigationItem_GetFromMessage(msg, param1);
*result = (INT_PTR)NavigationItem_TitleEditEndCb(item, (const wchar_t*)param2);
return TRUE;
case ML_MSG_NAVIGATION_ONDESTROY:
Navigation_DestroyCb();
*result = 0L;
return TRUE;
}
return FALSE;
}